MySQL 8.0 参考手册  / 第8章优化  / 8.9 控制查询优化器  /  8.9.2 可切换优化

8.9.2 可切换优化

系统optimizer_switch变量可以控制优化器的行为。它的值是一组标志,每个标志的值为on oroff以指示相应的优化器行为是启用还是禁用。该变量具有全局值和会话值,可以在运行时更改。可以在服务器启动时设置全局默认值。

要查看当前的优化器标志集,请选择变量值:

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,duplicateweedout=on,
                    subquery_materialization_cost_based=on,
                    use_index_extensions=on,
                    condition_fanout_filter=on,derived_merge=on,
                    prefer_ordering_index=on

要更改 的值 optimizer_switch,请分配一个由逗号分隔的一个或多个命令列表组成的值:

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

每个command值都应具有下表中显示的一种形式。

命令语法 意义
default 将每个优化重置为其默认值
opt_name=default 将命名优化设置为其默认值
opt_name=off 禁用命名优化
opt_name=on 启用命名优化

值中命令的顺序无关紧要,但default如果存在该命令,则会首先执行该命令。设置opt_name标志以 default将其设置 为默认值onoff默认值。opt_name 不允许在值中多次指定任何给定的值,这会导致错误。值中的任何错误都会导致赋值失败并出现错误,从而使值 optimizer_switch保持不变。

以下列表描述了允许的 opt_name标志名称,按优化策略分组:

当您为 赋值时 optimizer_switch,未提及的标志将保留其当前值。这使得在不影响其他行为的情况下在单个语句中启用或禁用特定优化器行为成为可能。该语句不依赖于存在哪些其他优化器标志以及它们的值是什么。假设启用了所有索引合并优化:

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,duplicateweedout=on,
                    subquery_materialization_cost_based=on,
                    use_index_extensions=on,
                    condition_fanout_filter=on,derived_merge=on,
                    prefer_ordering_index=on

如果服务器对某些查询使用 Index Merge Union 或 Index Merge Sort-Union 访问方法,并且您想检查优化器在没有它们的情况下是否性能更好,请像这样设置变量值:

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,duplicateweedout=on,
                    subquery_materialization_cost_based=on,
                    use_index_extensions=on,
                    condition_fanout_filter=on,derived_merge=on,
                    prefer_ordering_index=on