返回

帮助你了解MySQL执行计划是如何形成的:Optimizer Trace

后端

MySQL 5.6版本开始引入了Optimizer Trace这个工具,这个工具可以将执行计划是如何生成的打印出来,供自己查看和修改,本文档便详细介绍一下Optimizer Trace,并使用一个例子说明如何使用它。


MySQL执行计划的制定过程

MySQL 5.6版本之后,在执行SQL语句的过程中加入了一个新的工具——Optimizer Trace。Optimizer Trace通过记录整个执行计划生成的中间过程,我们通过这些信息,能够了解到MySQL究竟是怎么选择最终的执行计划。

在MySQL中,用户可以设置 OPTIMIZER_TRACE 环境变量来指定执行的SQL语句需要打印出详细信息,具体参数说明如下:

参数 含义
off 不打印任何Optimizer Trace信息
join_order 打印查询的表连接顺序
join_execution_order 打印连接表的顺序
index_merge 打印连接表的索引是否可以合并
rules 打印影响执行计划生成的规则
swap_join_order 打印连接顺序互换的可行性
intersection_prune 打印重叠键列裁剪的信息
dynamic_range 打印查询参数的影响因素
batch_mode 启动批处理模式,只记录元数据
slow 使Optimizer Trace走慢查询日志
all 打印所有可用的跟踪信息
  • 如果需要输出一条SQL语句执行的Optimizer Trace,需要在MySQL中执行如下语句:
set OPTIMIZER_TRACE='all'
  • 执行完以上语句后,再执行需要打印Optimizer Trace的SQL语句。

  • 打印出来的信息非常多,尤其是慢查询日志中更是详细。

以下是我摘抄的有关执行计划制定过程的部分记录信息:

table `billing`.`order` was joined with table `billing`.`subscription` because:
  - the best access path for `order` was covering index `order_id`
  - it is expected that 1 row(s) from `order` will be joined with 1 row(s) from `subscription`

从上面的执行过程来看,Optimizer Trace会详细记录一下内容:

  • 连接的顺序:table billing.order was joined with table billing.subscription

  • 连接的依据:因为order表使用了覆盖索引order_id

  • 预估连接的记录行数:预计order表会连接1行记录,subscription表连接1行记录。

  • 使用上述内容,用户可以通过以下思路来分析原因:

  • 确定哪一个表的连接顺序比较好

  • 确定哪个索引最好,为什么

  • 预估连接的记录行数是否合理

  • Optimizer Trace可以详细记录下这些中间过程,协助分析执行计划的制定过程。


实战使用

Optimizer Trace的使用也很简单,只需要打开需要打印的级别即可。

mysql> set optimizer_trace='all';
mysql> explain select count(*) from product;

执行完之后,我们就可以在查询信息中看到如下内容:

**** **** **** **** **** **** *** 1. best plan found ** **** **** **** **** **** **** *
cost=4.000000
mysql> select count(*) from product;
**** **** **** **** **** **** *** 2. other plans examined ** **** **** **** **** **** *
cost=9223372036854775807

可以看到优化器在第一次尝试中就找到了一个开销仅为4的计划,而且没有其他可能的计划。

其中cost的含义如下:

  • 若查询使用了索引,则代价为索引的总长度(具体地说是根据类型不同的索引会采用不同的估算方法)
  • 若查询使用的是全表扫描,则代价是表大小
  • 若查询使用了连接,则代价是读取第一张表的成本+读取第二张表的成本+连接两张表的成本

所以,如果索引的长度是4字节,而全表的大小是9223372036854775807字节,就会出现上述情况。


Optimizer Trace可视化工具——OTrace

除了在命令行中查看Optimizer Trace信息,还可以使用一个图形工具来查看。

MySQL Workbench中包含一个OTrace的可视化工具,选中SQL语句,右键,选择“Explain SQL Statement”,在“Execution Plan”标签中选择“Visual Explain”,就能够看到类似如下的一个图表:

MySQL Workbench OTrace


结束语

  • Optimizer Trace是一个非常实用的工具,可以详细打印出执行计划生成的中间过程,我们通过这些信息,能够了解到MySQL究竟是怎么选择最终的执行计划。

  • 要使用Optimizer Trace,只需在MySQL中执行set OPTIMIZER_TRACE='all'语句,然后执行需要打印Optimizer Trace的SQL语句即可。

  • Optimizer Trace的输出信息非常详细,用户可以通过分析这些信息来发现执行计划中存在的问题,并进行优化。