首页/数据/SQL 速查/EXPLAIN ANALYZE 实测统计
性能与执行计划72 条

EXPLAIN ANALYZE 实测统计

MySQL 8.0.18+ 会真正执行语句,输出每个节点的估算与实际 rows、耗时对比,用于发现估算偏差。

SQL 速查数据更新于 2026-10-13

EXPLAIN ANALYZE 是什么

MySQL 8.0.18 起的 EXPLAIN ANALYZE 会真正执行语句,再输出每个节点的估算行数与实际行数、实际耗时。它的价值在于暴露“估算偏差”:优化器以为要读 10 行、实际读了 10 万行时,执行计划的选择就会失准,这也是很多慢查询的真正根因。

基本信息

版本要求MySQL 8.0.18 及以上
行为真正执行语句,而不是只看计划
输出结构树形结构,每个节点给出 actual time、rows、loops
时间指标actual time 是首行时间..末行时间
行数指标rows 是每次循环的平均行数
总工作量约等于 rows 乘以 loops,嵌套循环内层必须乘 loops
偏差信号估算 rows 与实测 rows 差距大,说明统计信息需要更新

实测输出示例

实测输出示例
EXPLAIN ANALYZE
SELECT o.id, o.total
FROM orders o
WHERE o.user_id = 100
ORDER BY o.created_at DESC
LIMIT 10;

-- 输出片段:
-- -> Limit: 10 row(s)  (actual time=0.35..0.42 rows=10 loops=1)
--     -> Index lookup on o using idx_user_created (user_id=100)
--        (actual time=0.12..0.30 rows=8 loops=1)
-- 读法:内层每次循环约 8 行,外层只取 10 行,说明排序被索引顺序满足

输出字段读法

字段含义异常信号
actual time首行到末行的实测耗时与其它节点对比,找耗时占比最高的
rows每次循环的平均行数与估算值差很多说明统计信息不准
loops该节点执行的循环次数总读取量要乘以 loops 才是真实规模
cost(估算)优化器的相对代价估算它是相对值,不等于真实耗时
-> 缩进表示父子节点关系缩进越深越先执行

典型使用场景

  • 慢查询定位:找出真正耗时的节点,而不是凭感觉猜
  • 验证索引效果:确认访问方式是索引查找还是全表扫描
  • 排查估算偏差:决定是否要更新统计信息或调整索引
  • 上线前压测:在预发环境用真实数据量验证执行计划
  • 对比优化前后:同一语句两个版本的实测耗时
  • 排查 LIMIT 场景:确认取数是否能提前结束而不是全量排序
actual time 包含子节点的累计时间:父节点慢不一定代表它自己慢。先看叶子节点,再逐层往上看哪一层的增量耗时最高,那才是真正的瓶颈。
ANALYZE 会真正执行语句:重查询请挑低峰,写语句要放进事务并回滚。不同版本对写语句的实测支持范围不同,以所用版本的文档为准。

易错点

  • 在生产库随手 ANALYZE 重查询:语句会真实执行并带来瞬时压力,先评估扫描量再决定
  • 只看 rows 不看 loops:嵌套循环内层的 rows 是单次循环值,不乘 loops 会严重低估扫描量
  • 把估算 cost 当实际耗时:cost 只是优化器的相对代价,只有 actual time 是真实测量值
  • 用实测结果替代统计信息维护:估算偏差应通过更新统计信息解决,而不是靠每次实测绕过去

数据来源与参考

  • MySQL 8.0 Reference Manual §8.8.4 Obtaining Information with EXPLAIN ANALYZE
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌