- MySQL 8.0.18 引入了 EXPLAIN ANALYZE,它运行一个语句并生成 EXPLAIN 输出,同时提供时间和基于迭代器的额外信息,说明优化器的期望如何匹配实际执行。对于每个迭代器,包含以下信息:
- 预计执行成本(有些迭代器没有被成本模型考虑在内,因此不包括在估计中。)
- 返回的估计行数
- 返回第一行的时间
- 执行此迭代器(包括子迭代器,但不包括父迭代器)所花费的时间,以毫秒为单位。(当有多个循环时,此图显示每个循环的平均时间。)
- 迭代器返回的行数
- 循环次数
- EXPLAIN ANALYZE 向用户显示 MySQL 在查询上花费的时间以及原因。它将产生查询计划,并对其进行检测和执行,同时计算行数并度量执行计划中不同点上花费的时间,然后输出执行计划中各个迭代器的实际成本。执行完成后,EXPLAIN ANALYZE 将输出计划和度量结果,而不是查询结果。
- EXPLAIN ANALYZE 可以与 SELECT 语句以及多表 UPDATE 和 DELETE 语句一起使用。从MySQL 8.0.19开始,它也可以与 TABLE 语句一起使用
{EXPLAIN | DESCRIBE | DESC}
ANALYZE [FORMAT = TREE] select_statement;
参数 |
描述 |
select_statement |
查询语句 |
示例
EXPLAIN ANALYZE
SELECT * FROM t1 JOIN t2 ON (t1.c1 = t2.c2);
运行结果如下:
*************************** 1. row
***************************
EXPLAIN: -> Inner hash join (t2.c2 = t1.c1)
(cost=4.70 rows=6)
(actual time=0.032..0.035 rows=6 loops=1)
-> Table scan on t2 (cost=0.06 rows=6)
(actual time=0.003..0.005 rows=6 loops=1)
-> Hash
-> Table scan on t1 (cost=0.85 rows=6)
(actual time=0.018..0.022 rows=6 loops=1)
示例
EXPLAIN ANALYZE
SELECT * FROM t3 WHERE i > 8
运行结果如下:
*************************** 1. row
***************************
EXPLAIN: -> Filter: (t3.i > 8)
(cost=1.75 rows=5)
(actual time=0.019..0.021 rows=6 loops=1)
-> Table scan on t3 (cost=1.75 rows=15)
(actual time=0.017..0.019 rows=15 loops=1)
示例
EXPLAIN ANALYZE
SELECT * FROM t3 WHERE pk > 17;
运行结果如下:
*************************** 1. row
***************************
EXPLAIN: -> Filter: (t3.pk > 17)
(cost=1.26 rows=5)
(actual time=0.013..0.016 rows=5 loops=1)
-> Index range scan on t3 using
PRIMARY (cost=1.26 rows=5)
(actual time=0.012..0.014 rows=5 loops=1)
示例
EXPLAIN ANALYZE
SELECT * FROM t1 WHERE t1.a IN (SELECT t2.b FROM t2 WHERE id < 10)
运行结果如下:
*************************** 1. row
***************************
-> Nested loop inner join (cost=4.95 rows=9) (actual time=0.153..0.200
rows=9 loops=1)
-> Filter: (`<subquery2>`.b
is not null) (cost=2.83..1.80 rows=9)
(actual time=0.097..0.100 rows=9 loops=1)
-> Table scan on
<subquery2> (cost=0.29..2.61
rows=9) (actual time=0.001..0.002 rows=9 loops=1)
-> Materialize with
deduplication (cost=3.25..5.58 rows=9)
(actual time=0.090..0.092 rows=9 loops=1)
-> Filter: (t2.b is
not null) (cost=2.06 rows=9) (actual
time=0.037..0.042 rows=9 loops=1)
-> Filter: (t2.id
< 10) (cost=2.06 rows=9) (actual
time=0.036..0.040 rows=9 loops=1)
-> Index range scan on
t2 using PRIMARY (cost=2.06 rows=9) (actual time=0.035..0.038
rows=9 loops=1)
-> Index lookup on t1 using a
(a=`<subquery2>`.b) (cost=2.35
rows=1) (actual time=0.010..0.010 rows=1 loops=9)
1 row in set (0.01 sec)
- 嵌套查询(Nested loop)查询计划的解读顺序从最内部开始,然后回到最外层从上到下执行
注
- 查询执行信息使用 TREE 输出格式显示,其中节点代表迭代器。 EXPLAIN ANALYZE 始终使用 TREE 输出格式。
- 在 MySQL 8.0.21 及更高版本中,EXPLAIN ANALYZE 可以选择使用 FORMAT=TREE 明确指定; TREE 以外的格式仍然不受支持,也就是说 FORMAT=TRADITIONAL 或 FORMAT=JSON 都会引发错误。同时 explain_format 系统变量如果值为 JSON 或 TRADITIONAL ,也将返回错误,除非 FORMAT=TREE 被指定为语句的一部分。
- 从 MySQL 8.0.20 开始,可以使用 KILL QUERY 或 CTRL+C 终止此语句。
- EXPLAIN ANALYZE 不能与 FOR CONNECTION 一起使用。