三种 EXPLAIN 格式
MySQL 8.0.16 起 EXPLAIN 支持 FORMAT=TREE(树形,直观呈现嵌套循环顺序与估算成本)与 FORMAT=JSON(结构化,含 query_cost 等细节),默认的 TRADITIONAL 表格适合快速看访问类型与行数。树形看流程,JSON 看成本与机器可读性,表格用于速览与横向对比。
基本信息
| 适用 | MySQL 8.0.16+ 支持 TREE,5.7 与 8.0 均支持 JSON |
|---|---|
| 使用方式 | EXPLAIN FORMAT=TREE / JSON / TRADITIONAL 加在语句前 |
| 补充手段 | EXPLAIN ANALYZE(8.0.18+)返回真实耗时而非估算 |
| 典型工具 | JSON 输出配合 jq 提取成本字段 |
三种格式对照
三种格式对照
EXPLAIN FORMAT=TREE SELECT o.id FROM appdb.orders o JOIN appdb.users u ON u.id = o.user_id WHERE u.city='Hangzhou'; # 树形:看连接顺序与成本
EXPLAIN FORMAT=JSON SELECT o.id FROM appdb.orders o JOIN appdb.users u ON u.id = o.user_id WHERE u.city='Hangzhou'\G # JSON:含 query_cost 细节
EXPLAIN FORMAT=TRADITIONAL SELECT o.id FROM appdb.orders o JOIN appdb.users u ON u.id = o.user_id WHERE u.city='Hangzhou'; # 表格:速览
EXPLAIN ANALYZE SELECT o.id FROM appdb.orders o JOIN appdb.users u ON u.id = o.user_id WHERE u.city='Hangzhou'\G # 8.0.18+:真实执行耗时
EXPLAIN FORMAT=JSON SELECT ... \G | jq '.query_block.cost_info.query_cost' # 管道提取成本,便于对比不同写法字段怎么读
| 字段 | 含义 | 怎么用 |
|---|---|---|
| query_cost | 整个查询的估算成本 | 对比两种写法的成本差异,差异显著才值得改 |
| cost_info / read_cost | 单表或单步的读取成本 | 定位成本集中在哪个表 |
| rows_examined_per_scan | 每次扫描预计行数 | 数值过大说明缺少过滤条件或索引 |
| filtered | 过滤后剩余百分比 | 过低说明条件选择性差 |
| using_filesort / using_temporary_table | 需要额外排序或临时表 | 考虑补索引消除排序 |
| nested_loop | 连接步骤清单 | 从上到下读执行顺序,判断驱动表 |
典型使用场景
- 慢查询优化:先看 TREE 确认访问路径,再用 JSON 量化成本
- 改写 SQL 前后对比成本,避免凭感觉调整
- 接入自动化巡检:脚本解析 JSON 找出全表扫与 filesort
- 压测前评估连接顺序,确认驱动表是小结果集
- 验证索引是否被使用,过滤条件是否发生隐式转换
JSON 输出体积大,直接肉眼翻页效率低;用管道交给 jq 提取成本与访问类型字段,或者只对关心的子查询生成 JSON。
FORMAT=TREE 的缩进层级容易读反:树的缩进表达嵌套关系而非执行先后,不同连接类型的方向语义要以官方文档为准,别凭习惯推断。
查看计划的注意点
- 不同写法的成本只有在同一实例、同一份统计信息下对比才有意义
- EXPLAIN 不执行语句,看不到真实耗时,需要精确结论时用 EXPLAIN ANALYZE 复核
- 8.0.18 起 EXPLAIN ANALYZE 会真正执行查询,线上对写语句要格外谨慎
- JSON 里 filtered 百分比偏低说明条件选择性差,通常指向索引设计问题