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 |
| Set the named optimization to its default value |
| Disable the named optimization |
| 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 | Default |
|---|---|---|---|
| Batched Key Access | batched_key_access | Controls use of BKA join algorithm | OFF |
| Block Nested-Loop | block_nested_loop | Controls use of BNL join algorithm | ON |
| Engine Condition Pushdown | engine_condition_pushdown | Controls engine condition pushdown | ON |
| Index Condition Pushdown | index_condition_pushdown | Controls index condition pushdown | ON |
| Index Extensions | use_index_extensions | Controls use of index extensions | ON |
| Index Merge | index_merge | Controls all Index Merge optimizations | ON |
index_merge_intersection | Controls the Index Merge Intersection Access optimization | ON | |
index_merge_sort_union | Controls the Index Merge Sort-Union Access optimization | ON | |
index_merge_union | Controls the Index Merge Union Access optimization | ON | |
| Multi-Range Read | mrr | Controls the Multi-Range Read strategy | ON |
mrr_cost_based | Controls use of cost-based MRR if mrr=on | ON | |
| Semi-join | semijoin | Controls all semi-join strategies | ON |
firstmatch | Controls the semi-join FirstMatch strategy | ON | |
loosescan | Controls the semi-join LooseScan strategy (not to be confused with
LooseScan for GROUP BY) | ON | |
| Subquery materialization | materialization | Controls materialization (including semi-join materialization) | ON |
subquery_materialization_cost_based | Used cost-based materialization choice | ON |
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-to-EXISTS subquery
transformation. If the flag is on (the
default), the optimizer performs a cost-based choice between
subquery materialization and
IN-to-EXISTS subquery
transformation if either method could be used. If the flag is
off, the optimizer chooses subquery
materialization over
IN-to-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