首页/数据/SQL 速查/EXPLAIN 关键列总览
性能与执行计划72 条

EXPLAIN 关键列总览

id、type、key、key_len、rows、filtered、Extra 各列分别回答什么问题:理解列含义才能把输出读成有效信息。

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

EXPLAIN 关键列总览

理解 EXPLAIN 的输出要按列读:id 标识查询块,select_type 说明该行来自哪种子查询,type 是单表访问类型,key 是实际选中的索引,key_len 反映联合索引用到了前几列,rows 是预估扫描行数,filtered 是过滤后剩余比例,Extra 则给出排序、临时表等补充信息。把这些列串起来看,才能判断一条慢 SQL 卡在哪一步。只看 single 列容易误判,例如 possible_keys 有值但 key 为 NULL 表示索引没被选中。

基本信息

id查询块编号,同一 id 的行属于同一个 SELECT 块
select_type该行来源类型:SIMPLE、PRIMARY、SUBQUERY、DERIVED、UNION 等
type单表访问类型:const、eq_ref、ref、range、index、ALL
key实际使用的索引,NULL 表示未走索引
key_len索引查找用到的字节数,可推断命中前几列
rows预估扫描行数,不是返回行数
filtered条件过滤后剩余行的百分比(估算)
Extra补充信息:Using index、Using where、Using filesort 等

典型使用场景

  • 慢查询定位:从 type 与 key 判断是否走了预期索引
  • 联合索引验证:用 key_len 推算命中了前几列
  • 连接顺序确认:结合 id 与 rows 看驱动表是谁
  • 排序开销评估:看 Extra 里有没有 Using filesort
  • 覆盖索引检查:Using index 表示无需回表
  • 写语句预检:EXPLAIN 一条 UPDATE 看扫描量

示例

示例
EXPLAIN SELECT * FROM orders WHERE user_id = 100;

-- 输出列较多时,用 TREE 格式看单行摘要
EXPLAIN FORMAT=TREE SELECT * FROM orders WHERE user_id = 100;

-- JSON 格式便于程序化解析
EXPLAIN FORMAT=JSON SELECT * FROM orders WHERE user_id = 100;

-- 结合扫描行数与过滤比例判断是否需要补索引
EXPLAIN SELECT * FROM orders WHERE user_id = 100 AND status = 1;

重点列解读

列正常表现异常信号
typeref 或 rangeALL 或 index 表示大范围扫描
key命中预期索引NULL 表示未使用索引
key_len与索引前缀长度相符明显偏短说明只用到了前几列
rows数量级较小数量级偏大说明过滤不足
filtered接近 100很低说明大量行被读取后丢弃
ExtraUsing index 属好信号Using filesort、Using temporary 需关注
select_typeSIMPLE 或 PRIMARYDEPENDENT SUBQUERY 通常代价较高
possible_keys 只是候选清单,key 才是实际选择;两者不一致说明优化器放弃了那些索引,通常因为选择性不足或条件写法不合适。
rows 是估算值,偏差大时先更新统计信息(MySQL 用 ANALYZE TABLE,PostgreSQL 用 ANALYZE),再重新评估计划。
filtered 需要与 rows 一起看:两表连接时,rows 乘 filtered 才是传给下一步的估算行数,只盯一个数容易判断失误。

读列顺序建议

  • 先看是否有全表扫描:type 列整体扫一遍
  • 再看索引命中情况:key 与 key_len 决定实际用了哪棵索引的多少列
  • 然后看行数估算:rows 与 filtered 一起判断过滤是否有效
  • 最后看额外开销:Extra 里是否有文件排序或临时表
  • 结合 SQL 语义复核:计划合理但结果不对时,多半是写法问题

易错点

  • 把 rows 当成实际返回行数:它是基于统计信息的估算扫描量,需要与 EXPLAIN ANALYZE 的实测对照
  • 忽略 filtered 只看 rows:两表连接时 rows 乘 filtered 才是传给下一步的行数估算
  • 看到 possible_keys 有值就认为索引生效,实际 key 为 NULL
  • 用 TREE 或 JSON 格式时忘记不同版本字段有差异,跨版本对比计划产生误判
  • 只看单条 SQL 的计划,忽略它在整个业务链路里的调用频次与数据量

数据来源与参考

  • MySQL 8.0 Reference Manual §8.8.2 EXPLAIN Output Format
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌