首页/数据/数据库速查/EXPLAIN ANALYZE 与性能诊断链路
SQL 语法52 条

EXPLAIN ANALYZE 与性能诊断链路

8.0.18+ 的 EXPLAIN ANALYZE 实际执行并在计划上标注真实耗时与行数估计误差,是 SQL 性能诊断的完整闭环。

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

EXPLAIN ANALYZE 的价值

EXPLAIN 只给出估算的执行计划,EXPLAIN ANALYZE(MySQL 8.0.18+)会真正执行语句,并在计划树上标注每一步的实际耗时、实际返回行数与循环次数,把估算与实际摆在一起对比。估算行数与实际行数差出几个数量级,通常就是选错索引或统计信息失真的信号,这是定位 SQL 性能问题最有效的闭环。

基本信息

适用平台MySQL 8.0.18+、PostgreSQL、Oracle
语法EXPLAIN ANALYZE SELECT ...
输出形式TREE 格式计划 + actual time / rows / loops
关键对比估算 rows 与实际 rows 的比值
配套数据源慢日志、performance_schema.events_statements_summary_by_digest

典型使用场景

  • 慢查询语句改造前后对比,用实际耗时验证优化是否有效
  • 确认优化器是否选错索引,估算行数与实际行数严重偏离
  • 评估关联顺序与驱动表选择是否合理
  • 大表加索引前后做验证,避免上线后发现效果不符预期
  • 排查排序与临时表:确认是否出现 filesort 或落盘临时表

诊断示例

诊断示例
-- 真实执行并输出各节点的实际耗时与行数
EXPLAIN ANALYZE
SELECT o.id, o.amount, u.name
FROM orders o JOIN users u ON u.id = o.user_id
WHERE o.status = 'paid' AND o.created_at >= '2026-09-01'
ORDER BY o.created_at DESC LIMIT 50;
-- 只看估算计划(不执行),对比差异
EXPLAIN FORMAT = TREE SELECT ...;
-- 从慢日志里找候选语句
SELECT start_time, query_time, rows_examined, rows_sent, sql_text
FROM mysql.slow_log ORDER BY query_time DESC LIMIT 10;
-- 统计信息失真时先刷新
ANALYZE TABLE appdb.orders;

输出逐列读法

字段含义正常与异常
actual time该节点实际耗时区间(首行到末行)某一层占比极高说明瓶颈在该步
rows该节点实际返回行数与估算相差巨大说明统计信息失真
loops该节点被执行次数嵌套循环次数多时总耗时需乘以 loops
cost优化器估算代价,仅存在于估算计划只作参考,不代表真实耗时
filtered条件过滤后剩余行比例比例极低说明扫描了大量无用行
对比指标要一次看全:计划末尾的总耗时、每一步的 actual time 与 rows、以及估算行数三者的关系,才能判断是索引问题、统计信息问题还是数据分布问题。
EXPLAIN ANALYZE 会真执行语句并产生真实副作用:只在 SELECT 上使用,DML 语句要先改成对应查询再分析,或在测试库验证。

易错点

  • 在 UPDATE/DELETE 上直接跑 EXPLAIN ANALYZE:语句会被真实执行,造成数据被改且难以回滚
  • 只跑一次就下结论:单次采样受缓存命中与并发影响,重要结论要错峰多跑几次
  • 拿估算 cost 当耗时比较:cost 是优化器模型的相对值,不能跨语句比较,更不等于真实时间
  • 看到估算与实际差异大就急着加索引:先用 ANALYZE TABLE 刷新统计信息,很多偏差由此消除

数据来源与参考

  • MySQL 8.0 Reference Manual: EXPLAIN ANALYZE

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌