MySQL EXPLAIN FORMAT=JSON 中的 cost 与 rows_examined 解读

EXPLAIN FORMAT=JSON 中的 cost 是优化器基于统计信息估算的相对代价,单位为等价随机I/O次数,并非真实执行耗时;它不反映CPU、内存、锁等待等运行时开销,仅用于内部路径选择,DBA调优应重点关注 rows、key 和实际 Rows_examined 的对比。

mysql explain format=json 中的 cost 与 rows_examined 解读

EXPLAIN FORMAT=JSON 里的 cost 是估算值,不是真实执行开销

cost 字段出现在 EXPLAIN FORMAT=JSON 输出的 query_cost 或各节点的 cost_info 中,它由 MySQL 优化器基于统计信息(如索引基数、表行数、页大小)和固定代价模型算出,单位是“随机 I/O 次数等价值”。这个值不反映 CPU、内存或网络消耗,也不包含锁等待、刷脏页、Buffer Pool 缓存命中率波动等运行时因素。

常见误解是把它当“毫秒”或“执行耗时”,实际中:同一语句多次 EXPLAIN 可能返回不同 cost(统计信息更新后),但真实执行时间未必同步变化;加了 WHERE 条件后 cost 下降,却因索引失效导致实际变慢——这时得看 rows_examinedkey 是否被用上。

  • cost 主要用于优化器内部做 join 顺序、访问路径选择,对 DBA 调优参考价值有限
  • 对比不同执行计划时,cost 差异 > 20% 才值得关注;小差异大概率是统计误差
  • cost 极低但查询卡住,优先检查锁、长事务、磁盘 I/O 延迟,而非怀疑优化器算错

rows_examined 是真实扫描行数,但只在 profiling 开启后才准确

注意:EXPLAIN FORMAT=JSON **本身不输出 rows_examined**。这个字段实际来自 SHOW PROFILEperformance_schema.events_statements_summary_by_digest,或开启 slow_query_log 并设置 log_queries_not_using_indexes = ON 后的慢日志中的 Rows_examined 列。

真正和 EXPLAIN 直接关联的是 rows(JSON 中为 rows_estimated)——它是优化器对“该节点将扫描多少行”的预估,而 rows_examined 是执行后 MySQL 计数器累加的真实值。两者差距大,往往意味着:

  • 统计信息过期(ANALYZE TABLE 未及时运行)
  • 使用了函数/表达式导致索引无法范围扫描(如 WHERE YEAR(create_time) = 2023
  • 多表 JOIN 时驱动表选择错误,引发笛卡尔积放大
  • 存在隐式类型转换(如字符串字段与数字比较),使 key 显示为 NULLrows_examined 暴涨

如何用 rowskey 配合判断索引是否真生效

EXPLAIN FORMAT=JSON 的每个 table 节点里,重点看三处:rows(预估扫描行数)、key(实际选用索引名)、key_length(索引使用长度)。仅 keyNULL 不代表高效——可能只是用到了索引最左前缀,但后续条件仍需回表或全索引扫描。

百度文心百中

百度文心百中

百度大模型语义搜索体验中心

下载

典型陷阱:

  • key 有值,rows 却接近全表行数 → 索引区分度差(如性别字段建索引),或 WHERE 条件用了 LIKE '%abc'
  • key_length 小于索引定义长度(如联合索引 (a,b,c)key_length=4 表示只用到了 a)→ 后续 b/c 条件未走索引
  • rows 很小但执行慢 → 可能 Extra 里有 Using filesortUsing temporary,说明排序/分组没走索引

别信 cost,盯紧 rows + key + 实际 Rows_examined

线上调优最有效的组合是:先用 EXPLAIN FORMAT=JSONrowskey 是否合理,再查慢日志或 performance_schema 拿到真实 Rows_examined,最后比对二者差距。如果 rows 是 1000 但 Rows_examined 是 500000,基本可以确定统计信息不准或查询写法触发了优化器误判。

这时候改 SQL 比调优器参数更有效:拆分复杂条件、避免在索引列上运算、用 FORCE INDEX 临时验证路径、或者补上缺失的复合索引。MySQL 8.0+ 的直方图功能(ANALYZE TABLE ... UPDATE HISTOGRAM)能缓解部分 rows 估算偏差,但覆盖不了所有场景。

https://www.php.cn/faq/2034764.html

发表回复

Your email address will not be published. Required fields are marked *