Spec-Zone .ru
спецификации, руководства, описания, API

8.8.5.2. Controlling Switchable Optimizations

The optimizer_switch system variable enables control over optimizer behavior. Its value is a set of flags, each of which has a value of on or off to indicate whether the corresponding optimizer behavior is enabled or disabled. This variable has global and session values and can be changed at runtime. The global default can be set at server startup.

To see the current set of optimizer flags, select the variable value:

mysql> SELECT @@optimizer_switch\G*************************** 1. row ***************************@@optimizer_switch: index_merge=on,index_merge_union=on,                    index_merge_sort_union=on,                    index_merge_intersection=on,                    engine_condition_pushdown=on,                    index_condition_pushdown=on,                    mrr=on,mrr_cost_based=on,                    block_nested_loop=on,batched_key_access=off,                    materialization=on,semijoin=on,loosescan=on,                    firstmatch=on,                    subquery_materialization_cost_based=on,                    use_index_extensions=on

To change the value of optimizer_switch, assign a value consisting of a comma-separated list of one or more commands:

SET [GLOBAL|SESSION] optimizer_switch='command[,command]...';

Each command value should have one of the forms shown in the following table.

Command Syntax Meaning
default Reset every optimization to its default value
opt_name=default Set the named optimization to its default value
opt_name=off Disable the named optimization
opt_name=on Enable the named optimization

The order of the commands in the value does not matter, although the default command is executed first if present. Setting an opt_name flag to default sets it to whichever of on or off is its default value. Specifying any given opt_name more than once in the value is not permitted and causes an error. Any errors in the value cause the assignment to fail with an error, leaving the value of optimizer_switch unchanged.

The following table lists the permissible opt_name flag names, grouped by optimization strategy.

Optimization Flag Name Meaning
Batched Key Access batched_key_access Controls use of BKA join algorithm
Block Nested-Loop block_nested_loop Controls use of BNL join algorithm
Engine Condition Pushdown engine_condition_pushdown Controls engine condition pushdown
Index Condition Pushdown index_condition_pushdown Controls index condition pushdown
Index Extensions use_index_extensions Controls use of index extensions
Index Merge index_merge Controls all Index Merge optimizations
index_merge_intersection Controls the Index Merge Intersection Access optimization
index_merge_sort_union Controls the Index Merge Sort-Union Access optimization
index_merge_union Controls the Index Merge Union Access optimization
Multi-Range Read mrr Controls the Multi-Range Read strategy
mrr_cost_based Controls use of cost-based MRR if mrr=on
Semi-join semijoin Controls all semi-join strategies
firstmatch Controls the semi-join FirstMatch strategy
loosescan Controls the semi-join LooseScan strategy (not to be confused withLooseScan for GROUP BY)
Subquery materialization materialization Controls materialization (including semi-join materialization)
subquery_materialization_cost_based Used cost-based materialization choice

The block_nested_loop and batched_key_access flags were added in MySQL 5.6.3. For batched_key_access to have any effect when set to on, the mrr flag must also be on. Currently, the cost estimation for MRR is too pessimistic. Hence, it is also necessary for mrr_cost_based to be off for BKA to be used.

semijoin, firstmatch, loosescan, and materialization flags were added in MySQL 5.6.5 to enable control over semi-join and subquery materialization strategies. The semijoin flag controls whether semi-joins are used. If it is set to on, the firstmatch and loosescan flags enable finer control over the permitted semi-join strategies. The materialization flag controls whether subquery materialization is used. If semijoin and materialization are both on, semi-joins also use materialization where applicable. These flags are on by default.

The subquery_materialization_cost_based was added in MySQL 5.6.7 to enable control over the choice between subquery materialization and IN -> EXISTS subquery transformation. If the flag is on (the default), the optimizer performs a cost-based choice between subquery materialization and IN -> EXISTS subquery transformation if either method could be used. If the flag is off, the optimizer chooses subquery materialization over IN -> EXISTS subquery transformation, which was the previous behavior before MySQL 5.6.7.

For more information about individual optimization strategies, see the following sections:

When you assign a value to optimizer_switch, flags that are not mentioned keep their current values. This makes it possible to enable or disable specific optimizer behaviors in a single statement without affecting other behaviors. The statement does not depend on what other optimizer flags exist and what their values are. Suppose that all Index Merge optimizations are enabled:

mysql> SELECT @@optimizer_switch\G*************************** 1. row ***************************@@optimizer_switch: index_merge=on,index_merge_union=on,                    index_merge_sort_union=on,                    index_merge_intersection=on,                    engine_condition_pushdown=on,                    index_condition_pushdown=on,                    mrr=on,mrr_cost_based=on,                    block_nested_loop=on,batched_key_access=off,                    materialization=on,semijoin=on,loosescan=on,                    firstmatch=on,                    subquery_materialization_cost_based=on,                    use_index_extensions=on

If the server is using the Index Merge Union or Index Merge Sort-Union access methods for certain queries and you want to check whether the optimizer will perform better without them, set the variable value like this:

mysql> SET
        optimizer_switch='index_merge_union=off,index_merge_sort_union=off';mysql> SELECT @@optimizer_switch\G*************************** 1. row ***************************@@optimizer_switch: index_merge=on,index_merge_union=off,                    index_merge_sort_union=off,                    index_merge_intersection=on,                    engine_condition_pushdown=on,                    index_condition_pushdown=on,                    mrr=on,mrr_cost_based=on,                    block_nested_loop=on,batched_key_access=off,                    materialization=on,semijoin=on,loosescan=on,                    firstmatch=on,                    subquery_materialization_cost_based=on,                    use_index_extensions=on