explain format=json 中的 cost_info 字段提供优化器预估的 read_cost(i/o)、eval_cost(cpu)和 prefix_cost(累计成本),均为相对值,用于执行计划对比,不反映真实耗时或锁、网络等运行时开销。

EXPLAIN FORMAT=JSON 能看到比传统 EXPLAIN 更细粒度的成本估算,但默认不显示“执行耗时”,它展示的是优化器预估的 I/O、CPU、内存等成本项——你要找的“详细执行成本”就藏在 cost_info 字段里,而不是运行时真实耗时。
怎么看 cost_info 里的 I/O 和 CPU 成本?
MySQL 8.0 的 FORMAT=JSON 输出中,每个表访问节点(table 对象)下都有一个 cost_info 字段,里面包含三项关键预估:
-
read_cost:主要是随机 I/O 预估(比如索引查找、回表),单位是“页读取开销” -
eval_cost:行数据过滤、计算的 CPU 开销(和扫描行数成正比) -
prefix_cost:到该节点为止的累计成本(含前面所有表 + 当前表)
示例语句:
EXPLAIN FORMAT=JSON SELECT * FROM orders WHERE user_id = 123 AND status = 'paid';然后在 JSON 输出里定位到
"table": {"name": "orders", ...} 下的 "cost_info" 对象。为什么有些查询没显示 cost_info?
不是所有访问路径都会输出 cost_info,常见原因有:
- 使用了
UNION或子查询且未被扁平化,部分分支可能被省略成本估算 - 启用了
optimizer_switch='condition_fanout_filter=off'等非默认开关,干扰成本模型 - 查询涉及临时表(
Using temporary)或文件排序(Using filesort),成本会合并进外层prefix_cost,不单独列cost_info - 你用的是视图或 CTE,而 MySQL 8.0.19 之前对 CTE 的成本估算支持不完整
cost_info 数值怎么理解?单位是什么?
这些数字没有绝对物理单位,是优化器内部归一化的相对成本值,用于横向比较不同执行计划。但你可以通过以下方式辅助判断:
-
read_cost显著高于eval_cost→ 可能缺索引,导致大量随机 I/O -
eval_cost异常高(比如远超rows× 0.2)→ 可能有复杂表达式、函数或隐式类型转换拖慢行过滤 - 对比两个相似查询的
prefix_cost:差值 > 2 倍通常说明执行计划质量差异明显 - 注意:这些成本不包含网络传输、锁等待、刷脏页等运行时开销
真正影响响应时间的,往往是那些 cost_info 没法体现的部分——比如大结果集的网络发送、长事务下的锁竞争、Buffer Pool 命中率低导致的真实磁盘读。别只盯着数字,要结合 SHOW PROFILE 或 performance_schema 查实际阶段耗时。










