All Products
Search
Document Center

PolarDB:Use Hybrid Plan to accelerate wide table queries

Last Updated:Mar 30, 2026

Wide table queries that filter on a few columns but retrieve all columns create a read amplification problem: a columnstore index handles filtering efficiently, but fetching every projected column through it is expensive. A row store index avoids that amplification, but loses columnar filtering speed. Hybrid Plan combines both indexes in a single query execution to get the best of each.

image.png

How it works

Hybrid Plan splits execution into two stages:

  1. The optimizer uses the In-Memory Column Index (IMCI) to filter rows and retrieve their primary keys.

  2. The system uses those primary keys to look up the full row data from the InnoDB primary index.

This eliminates read amplification: IMCI handles the fast columnar scan, and InnoDB returns only the matching rows in full.

Applicability

  • Cluster edition: PolarDB for MySQL Enterprise Edition

  • Supported versions:

    • PolarDB for MySQL 8.0.1, revision 8.0.1.1.37 or later

    • PolarDB for MySQL 8.0.2, revision 8.0.2.2.23.1 or later

Use cases

Wide table queries that return 15 or more columns.

Limitations

Tables that provide output columns for the query must have an explicitly defined primary key.

Note

If Hybrid Plan cannot accelerate a slow SQL statement due to limitations such as the table type, contact us for help.

Parameters

Two parameters control Hybrid Plan. They work at different levels and follow a clear priority order:

  1. imci_enable_hybrid_plan — controls the feature globally. When set to ON, the optimizer evaluates each query and automatically applies Hybrid Plan when it estimates a cost benefit.

  2. imci_optimizer_switch — a per-query hint. When force_hybrid_index_search=ON is set in a hint, it forces Hybrid Plan for that statement regardless of the optimizer's cost estimate.

Priority: A per-query hint (force_hybrid_index_search=ON) overrides the optimizer's automatic decision. The optimizer only decides when no hint is present and imci_enable_hybrid_plan is ON.

Parameter Default Description
imci_enable_hybrid_plan ON Enables Hybrid Plan globally. Set to OFF to disable the feature.
imci_optimizer_switch force_hybrid_index_search=OFF Per-query override. Set force_hybrid_index_search=ON in a hint to force Hybrid Plan for a specific statement.

Enable and verify Hybrid Plan

This section uses SELECT * FROM t1; as an example.

Step 1: Connect to your cluster

Connect to the PolarDB cluster. For details, see Connect to a database cluster.

Step 2: Enable the feature

Set imci_enable_hybrid_plan to ON. The optimizer then automatically applies Hybrid Plan to eligible wide table queries.

SET imci_enable_hybrid_plan=ON;

Step 3: Force a specific query to use Hybrid Plan (optional)

If the optimizer does not select Hybrid Plan for a query (for example, its cost estimate favors another plan), add a hint to override the decision:

SELECT /*+ SET_VAR(imci_optimizer_switch='force_hybrid_index_search=ON') */ * FROM t1;

Step 4: Verify that Hybrid Plan is active

Run EXPLAIN on the query to confirm that Hybrid Plan is in use. When active, the execution plan includes the HybridIndexSearch operator.

EXPLAIN SELECT /*+ SET_VAR(imci_optimizer_switch='force_hybrid_index_search=ON') */ * FROM t1;

Expected output:

+----+-------------------------+------+---------------------------------------------------------------+
| ID | Operator                | Name | Extra Info                                                    |
+----+-------------------------+------+---------------------------------------------------------------+
|  1 | Select Statement        |      | IMCI Execution Plan (max_dop = 32, max_query_mem = unlimited) |
|  2 | └─HybridIndexSearch     |      | Used table: t1                                                |
|  3 |   └─Compute Scalar      |      |                                                               |
|  4 |     └─Table Scan        | t1   |                                                               |
+----+-------------------------+------+---------------------------------------------------------------+
4 rows in set (0.02 sec)

The HybridIndexSearch operator in row 2 confirms that Hybrid Plan is active. Row 1 shows the IMCI execution context; row 4 confirms the InnoDB table scan for full row retrieval.

Performance test

The following test uses the OnTime dataset from ClickHouse. The OnTime table has 109 columns, making it a representative wide table. The table schema was modified to include an explicit primary key. The modified schema is as follows:

CREATE TABLE `ontime` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Year` year(4) DEFAULT NULL,
  `Quarter` tinyint(4) DEFAULT NULL,
  `Month` tinyint(4) DEFAULT NULL,
  `DayofMonth` tinyint(4) DEFAULT NULL,
  `DayOfWeek` tinyint(4) DEFAULT NULL,
  `FlightDate` date DEFAULT NULL,
  `UniqueCarrier` char(7) DEFAULT NULL,
  `AirlineID` int(11) DEFAULT NULL,
  `Carrier` char(2) DEFAULT NULL,
  `TailNum` varchar(50) DEFAULT NULL,
  `FlightNum` varchar(10) DEFAULT NULL,
  `OriginAirportID` int(11) DEFAULT NULL,
  `OriginAirportSeqID` int(11) DEFAULT NULL,
  `OriginCityMarketID` int(11) DEFAULT NULL,
  `Origin` char(5) DEFAULT NULL,
  `OriginCityName` varchar(100) DEFAULT NULL,
  `OriginState` char(2) DEFAULT NULL,
  `OriginStateFips` varchar(10) DEFAULT NULL,
  `OriginStateName` varchar(100) DEFAULT NULL,
  `OriginWac` int(11) DEFAULT NULL,
  `DestAirportID` int(11) DEFAULT NULL,
  `DestAirportSeqID` int(11) DEFAULT NULL,
  `DestCityMarketID` int(11) DEFAULT NULL,
  `Dest` char(5) DEFAULT NULL,
  `DestCityName` varchar(100) DEFAULT NULL,
  `DestState` char(2) DEFAULT NULL,
  `DestStateFips` varchar(10) DEFAULT NULL,
  `DestStateName` varchar(100) DEFAULT NULL,
  `DestWac` int(11) DEFAULT NULL,
  `CRSDepTime` int(11) DEFAULT NULL,
  `DepTime` int(11) DEFAULT NULL,
  `DepDelay` int(11) DEFAULT NULL,
  `DepDelayMinutes` int(11) DEFAULT NULL,
  `DepDel15` int(11) DEFAULT NULL,
  `DepartureDelayGroups` int(11) DEFAULT NULL,
  `DepTimeBlk` varchar(20) DEFAULT NULL,
  `TaxiOut` int(11) DEFAULT NULL,
  `WheelsOff` int(11) DEFAULT NULL,
  `WheelsOn` int(11) DEFAULT NULL,
  `TaxiIn` int(11) DEFAULT NULL,
  `CRSArrTime` int(11) DEFAULT NULL,
  `ArrTime` int(11) DEFAULT NULL,
  `ArrDelay` int(11) DEFAULT NULL,
  `ArrDelayMinutes` int(11) DEFAULT NULL,
  `ArrDel15` int(11) DEFAULT NULL,
  `ArrivalDelayGroups` int(11) DEFAULT NULL,
  `ArrTimeBlk` varchar(20) DEFAULT NULL,
  `Cancelled` tinyint(4) DEFAULT NULL,
  `CancellationCode` char(1) DEFAULT NULL,
  `Diverted` tinyint(4) DEFAULT NULL,
  `CRSElapsedTime` int(11) DEFAULT NULL,
  `ActualElapsedTime` int(11) DEFAULT NULL,
  `AirTime` int(11) DEFAULT NULL,
  `Flights` int(11) DEFAULT NULL,
  `Distance` int(11) DEFAULT NULL,
  `DistanceGroup` tinyint(4) DEFAULT NULL,
  `CarrierDelay` int(11) DEFAULT NULL,
  `WeatherDelay` int(11) DEFAULT NULL,
  `NASDelay` int(11) DEFAULT NULL,
  `SecurityDelay` int(11) DEFAULT NULL,
  `LateAircraftDelay` int(11) DEFAULT NULL,
  `FirstDepTime` varchar(10) DEFAULT NULL,
  `TotalAddGTime` varchar(10) DEFAULT NULL,
  `LongestAddGTime` varchar(10) DEFAULT NULL,
  `DivAirportLandings` varchar(10) DEFAULT NULL,
  `DivReachedDest` varchar(10) DEFAULT NULL,
  `DivActualElapsedTime` varchar(10) DEFAULT NULL,
  `DivArrDelay` varchar(10) DEFAULT NULL,
  `DivDistance` varchar(10) DEFAULT NULL,
  `Div1Airport` varchar(10) DEFAULT NULL,
  `Div1AirportID` int(11) DEFAULT NULL,
  `Div1AirportSeqID` int(11) DEFAULT NULL,
  `Div1WheelsOn` varchar(10) DEFAULT NULL,
  `Div1TotalGTime` varchar(10) DEFAULT NULL,
  `Div1LongestGTime` varchar(10) DEFAULT NULL,
  `Div1WheelsOff` varchar(10) DEFAULT NULL,
  `Div1TailNum` varchar(10) DEFAULT NULL,
  `Div2Airport` varchar(10) DEFAULT NULL,
  `Div2AirportID` int(11) DEFAULT NULL,
  `Div2AirportSeqID` int(11) DEFAULT NULL,
  `Div2WheelsOn` varchar(10) DEFAULT NULL,
  `Div2TotalGTime` varchar(10) DEFAULT NULL,
  `Div2LongestGTime` varchar(10) DEFAULT NULL,
  `Div2WheelsOff` varchar(10) DEFAULT NULL,
  `Div2TailNum` varchar(10) DEFAULT NULL,
  `Div3Airport` varchar(10) DEFAULT NULL,
  `Div3AirportID` int(11) DEFAULT NULL,
  `Div3AirportSeqID` int(11) DEFAULT NULL,
  `Div3WheelsOn` varchar(10) DEFAULT NULL,
  `Div3TotalGTime` varchar(10) DEFAULT NULL,
  `Div3LongestGTime` varchar(10) DEFAULT NULL,
  `Div3WheelsOff` varchar(10) DEFAULT NULL,
  `Div3TailNum` varchar(10) DEFAULT NULL,
  `Div4Airport` varchar(10) DEFAULT NULL,
  `Div4AirportID` int(11) DEFAULT NULL,
  `Div4AirportSeqID` int(11) DEFAULT NULL,
  `Div4WheelsOn` varchar(10) DEFAULT NULL,
  `Div4TotalGTime` varchar(10) DEFAULT NULL,
  `Div4LongestGTime` varchar(10) DEFAULT NULL,
  `Div4WheelsOff` varchar(10) DEFAULT NULL,
  `Div4TailNum` varchar(10) DEFAULT NULL,
  `Div5Airport` varchar(10) DEFAULT NULL,
  `Div5AirportID` int(11) DEFAULT NULL,
  `Div5AirportSeqID` int(11) DEFAULT NULL,
  `Div5WheelsOn` varchar(10) DEFAULT NULL,
  `Div5TotalGTime` varchar(10) DEFAULT NULL,
  `Div5LongestGTime` varchar(10) DEFAULT NULL,
  `Div5WheelsOff` varchar(10) DEFAULT NULL,
  `Div5TailNum` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=58592318 DEFAULT CHARSET=latin1 COMMENT='columnar=1'

Test query:

SELECT * FROM ontime ORDER BY ArrTime LIMIT 1000;

All queries ran from a cold start.

Execution strategy Query time
Row store only 232.48 seconds
Columnstore index (IMCI) only 2.56 seconds
Hybrid Plan 0.33 seconds

Hybrid Plan is 7.8x faster than columnstore-only and 704x faster than row-store-only for this workload.