EXPLAIN ANALYZE 自 MySQL 8.0.18 起原生支持,低于该版本会报语法错误;它真实执行查询,返回各算子的实际耗时、处理行数和循环次数,用于精准定位性能瓶颈。

EXPLAIN ANALYZE 在 MySQL 8.0 中是否可用
MySQL 8.0.18 起才原生支持 EXPLAIN ANALYZE,低于该版本执行会报错 ERROR 1064 (42000): You have an error in your SQL syntax。不是所有 8.0.x 都行——必须确认具体小版本号:
SELECT VERSION();返回如
8.0.23 或更高才可使用。
执行 EXPLAIN ANALYZE 的基本要求和限制
它只对 SELECT、DELETE、INSERT ... SELECT 和 REPLACE ... SELECT 有效,不能用于纯 INSERT VALUES 或 UPDATE 语句。执行时会真实运行查询(含 I/O 和计算),所以:
- 带副作用的子查询会被执行两次(一次分析,一次统计),可能引发重复写入或触发器误触发
- 大表全扫描会真实耗时,别在生产环境直接跑未加
LIMIT的EXPLAIN ANALYZE SELECT * - 结果中
actual_time字段显示每个节点实际耗时(单位毫秒),但精度受系统调度影响,多次执行数值会有浮动
怎么看懂 EXPLAIN ANALYZE 的输出关键字段
输出是树状嵌套结构,每行代表一个执行节点。重点关注三组时间字段:
-
actual_time:格式为0.123..4.567,表示该节点启动到结束的耗时范围(最小…最大) -
rows_examined:该节点实际读取的行数(区别于rows的预估) -
rows_sent:最终向上层返回的行数(可用于判断是否早期过滤失效)
例如发现某个 Index lookup 节点 rows_examined 是 10 万但 rows_sent 只有 1,说明索引虽命中,但大量行被 WHERE 条件过滤掉——这时要检查索引是否覆盖了过滤字段。
容易被忽略的性能干扰点
缓存状态会显著影响 actual_time 数值:
- InnoDB 缓冲池预热不足时,首次
EXPLAIN ANALYZE会包含大量磁盘 I/O,后续执行变快,不能只看一次结果 - Query Cache 在 MySQL 8.0 中已被移除,不用考虑它,但要注意 OS page cache 是否被其他进程刷掉
- 如果语句涉及临时表(
Using temporary),actual_time里会包含建表、排序、回表全过程,此时应结合SHOW PROFILE定位瓶颈阶段
真正要定位慢点,得比对「预估行数 vs 实际行数」+「各节点耗时占比」+「是否触发磁盘临时表」,单看总耗时不解决问题。


















