The optimizer estimates execution costs based on statistics and sampled data. When those estimates deviate significantly from actual runtime values, the optimizer may choose a suboptimal execution plan. Adaptive execution plan switching detects this divergence at runtime and switches to a better plan automatically, without requiring manual intervention.
Two modes are supported:
Adaptive row-column routing: Redirects slow queries from row store nodes to column store (IMCI) nodes when the actual scan volume exceeds the estimated threshold.
Adaptive selection of ordered indexes: When the actual rows scanned on an ordered index selected by the
prefer_ordering_indexoptimization exceed the threshold, the system switches execution to column store, preventing unnecessary I/O and CPU overhead.
How it works
Both modes follow the same three-phase mechanism:
Optimization phase: The optimizer marks row count thresholds for each query block and the entire query, then adds them to monitoring metadata. If the optimizer does not select IMCI, or selects an ordered index due to
prefer_ordering_index, it calculates the threshold for triggering a plan switch.Execution phase: As the query runs, the database tracks rows scanned in the critical path using integer comparisons only—no performance overhead. When the scanned row count reaches the threshold, the system evaluates whether to switch to an alternative plan.
Plan switch: Before switching, the database ensures that no partial results have been returned to the client. After switching, it clears any cached intermediate results and continues execution under the new plan.
For clusters running version 8.0.1.1.49 or later (or 8.0.2.2.29 or later), the threshold for adaptive row-column routing is controlled by loose_adaptive_cost_threshold_for_imci. For earlier versions, it is derived from loose_cost_threshold_for_imci.
The following diagram illustrates the flow for adaptive row-column routing.
Prerequisites
Before enabling adaptive execution plan switching, make sure your cluster meets the version requirements for the mode you want to use.
Adaptive row-column routing (imci_chosen=on):
PolarDB for MySQL 8.0.1, revision version 8.0.1.1.39 or later
PolarDB for MySQL 8.0.2, revision version 8.0.2.2.29 or later
Adaptive selection of ordered indexes (ordering_index=on):
PolarDB for MySQL 8.0.1, revision version 8.0.1.1.47 or later
PolarDB for MySQL 8.0.2, revision version 8.0.2.2.29 or later
Enable or disable adaptive execution plan switching
Log in to the PolarDB console and go to the Parameters page of your cluster. For configuration steps, see Configure cluster and node parameters.
Set loose_adaptive_plans_switch to one of the following values:
'imci_chosen=on'— enables adaptive row-column routing'ordering_index=on'— enables adaptive selection of ordered indexes'imci_chosen=on,ordering_index=on'— enables both modesSet either sub-key to
'off'to disable the corresponding mode
The following table describes all configurable parameters.
| Parameter | Scope | Description | Minimum version |
|---|---|---|---|
loose_adaptive_plans_switch | Global/Session | Controls which adaptive switching modes are active. Sub-keys: imci_chosen (default: ON) and ordering_index (default: OFF). Set imci_chosen=ON to enable adaptive row-column routing; column store nodes must be correctly configured. Set ordering_index=ON to enable adaptive selection of ordered indexes. | 8.0.1.1.39 (imci_chosen) / 8.0.1.1.47 (ordering_index) |
loose_adaptive_cost_threshold_for_imci | Global/Session | Cost threshold for triggering adaptive row-column routing. Valid values: 1–18,446,744,073,709,551,615. Default: 50000. | 8.0.1.1.49 or 8.0.2.2.29 |
loose_adaptive_plans_max_time | Global/Session | Maximum execution time (ms) for a query to be eligible for adaptive plan switching. If a query runs longer than this value before reaching the row threshold, no plan switch occurs. Valid values: 0–1,800,000. Default: 500. Unit: milliseconds. | — |
loose_adaptive_ordering_rows_threshold | Global/Session | Row scan checkpoint for adaptive selection of ordered indexes. A lower value causes more frequent checks and earlier switching. Valid values: 0–4,294,967,295. Default: 50000. | — |
Why the default solutions fall short
Before adaptive execution plan switching was available, addressing misrouted queries or poor index selection required one of two manual approaches:
Lower the column store cost threshold globally: This routes more queries to column store nodes, but also sends short, lightweight queries to IMCI—increasing load on column store nodes and potentially blocking other workloads.
Use statement outline to fix specific query templates: The statement outline feature can force a specific query to use column store or disable
prefer_ordering_index:-- Force a query to use column store CALL dbms_outln.add_optimizer_outline("<schema_name>", "/*+ SET_VAR(cost_threshold_for_imci=0) SET_VAR(imci_ap_threshold=0) */", "<query>"); -- Disable prefer_ordering_index for a specific query template CALL dbms_outln.add_optimizer_outline("<schema_name>", "/*+ SET_VAR(optimizer_switch='prefer_ordering_index=off') */", "<query>");This approach is precise but adds significant operational costs—each problematic query template must be identified and managed individually.
Adaptive execution plan switching addresses both problems automatically: it switches plans only when actual runtime data confirms the optimizer's estimate was wrong, leaving correctly estimated queries unaffected.
When to use each approach: Use loose_adaptive_plans_switch (automatic) as the default—it requires no per-query configuration and responds to runtime evidence. Use statement outline (manual) when you need deterministic behavior for a specific query template, regardless of runtime statistics.
Verify adaptive switching activity
Run the following statement to check the total number of adaptive plan switches since the feature was enabled:
SHOW GLOBAL STATUS LIKE 'Adaptive_plan_used';| Variable | Scope | Description |
|---|---|---|
Adaptive_plan_used | Global | Total number of adaptive plan switches performed since the feature was enabled. |