首页/数据/数据库速查/EXPLAIN 读执行计划:type / key / rows / Extra
SQL 语法52 条

EXPLAIN 读执行计划:type / key / rows / Extra

用 EXPLAIN 看优化器怎么执行:访问类型、命中索引、估算行数与额外动作(filesort、temporary)。调优从它开始。

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

EXPLAIN 怎么读

EXPLAIN 把优化器的执行计划摊开来看:用哪张表、用什么访问方式、命中哪个索引、预计扫描多少行、还有哪些额外动作。读计划要回答三个问题——是否走了索引、扫描行数是否可接受、有没有额外的排序或临时表。它给出的是基于统计信息的估算,要拿到真实行数与耗时,需要用能实际执行语句的分析写法。

基本信息

用途查看语句的执行计划
语法EXPLAIN 语句 / EXPLAIN FORMAT=JSON 语句
关键列type / key / key_len / rows / filtered / Extra
访问类型顺序const → eq_ref → ref → range → index → ALL
行数口径rows 为估算值,来自统计信息
实测手段8.0.18 起可实际执行语句获取真实行数

典型使用场景

  • 慢查询优化的第一步:先看计划,再决定加索引还是改写法
  • 上线前评审:新语句是否存在全表扫描
  • 索引效果验收:加索引前后对比访问类型、使用索引与扫描行数
  • 分页与排序排查:确认排序是否借用了索引顺序
  • 连接查询排查:确认被驱动表是否走了索引
  • 核心语句的定期巡检:发现执行计划悄悄发生变化

使用与解读

使用与解读
EXPLAIN SELECT id, amount FROM orders   # 只取需要的列,计划更贴近真实
WHERE user_id = 42 AND status = 1   # 等值条件,便于观察索引命中
ORDER BY created_at DESC LIMIT 10;
EXPLAIN FORMAT=JSON SELECT ... ;   # 结构化输出,附带成本估算
EXPLAIN ANALYZE SELECT ... ;   # 8.0.18 起实际执行,返回真实行数与耗时

常见计划改进

常见计划改进
EXPLAIN SELECT id FROM orders WHERE status = 1;   # 条件列无索引,计划里通常是全表扫描
ALTER TABLE orders ADD INDEX idx_status_created (status, created_at);   # 补上复合索引
EXPLAIN SELECT id FROM orders WHERE status = 1 ORDER BY created_at DESC LIMIT 10;   # 再看访问类型与附加信息

逐列读法

列含义异常信号
id查询块序号,同号按从上到下执行子查询会出现多个编号
select_type查询类型,如简单、子查询、联合出现子查询要评估能否改写
table当前访问的对象排在前面的通常是驱动表
type访问类型,性能第一指标ALL 是全表扫描,优先优化
possible_keys候选索引为空说明没有可用索引
key实际使用的索引为 NULL 说明索引没用上
key_len索引使用长度可判断复合索引用到几列
rows估算扫描行数数值巨大是成本主要来源
EXPLAIN 只做估算不执行语句,行数来自统计信息,可能与真实值差一个数量级;需要实测时用 8.0.18 起的分析写法,它会真正执行语句并给出实际行数。
不能只看是否用上了索引:复合索引被命中的前缀不对时,虽然显示了索引名,过滤效果依然很差,要结合索引使用长度与估算行数一起判断。
对生产语句直接做实测分析会真正执行这条语句并产生负载,写语句尤其危险;慢查询排查应安排在只读从库或业务低峰期进行。

计划检查清单

  • 访问类型是否落在等值或范围级别,有无全表扫描
  • 实际使用的索引是否与预期一致,复合索引用到几列
  • 估算扫描行数与最终返回行数的比例是否合理
  • 是否出现额外排序或临时表
  • 连接查询中被驱动表是否走了索引
  • 统计信息是否过期,是否需要重新收集后再看计划
同一语句在不同数据量下会得到不同计划:统计信息更新、数据分布变化都会让优化器改选索引,因此核心语句的执行计划要定期取样比对,而不是上线时看一次就存档。

易错点

  • 只确认用上了索引就放心:复合索引前缀不对时命中索引但过滤极差,必须结合索引长度与扫描行数一起看
  • 忽略巨大的估算扫描行数:行数才是成本主体,只看访问类型会漏掉真正的瓶颈
  • 在统计信息过期时读计划:估算偏差会让优化器选错索引,重要改动前后都应先更新统计信息
  • 对生产语句直接做实测分析:语句会被真实执行并带来负载,写语句风险更高,应限制在从库或低峰期
  • 只改语句不动索引:条件列没有索引时怎么写都是全表扫描,索引与写法必须一起评估

数据来源与参考

  • MySQL 8.0 Reference Manual: EXPLAIN Output Format

相关工具

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