当我第一次在控制台敲下EXPLAIN SELECT * FROM users
时出现的表格令我困惑不已——这个看起来像Excel表格的输出到底隐藏着怎样的秘密?作为DBA十年的老张告诉我:"这就像是X光片里的骨骼图"
Part1. EXPLAIN输出的基础架构
我们来看一个典型的输出案例:
+----+-------------+-------+------+---------------+-----+---------+-----+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-----+---------+-----+------|-------+
| 1 | SIMPLE | users | ALL │ NULL │ NULL│ NULL │ NULL│10000 │ │
这张表里每个字段都对应着重要的诊断信息:
- id不仅是序号编号还反映了子查询的执行顺序(相同数字表示并行)
- select_type中PRIMARY/UNION/DEPENDENT SUBQUERY暗示了语句复杂度层级
- type=ALL就像红色警报说明正在全表扫描
实战技巧:当看到Using temporary或Using filesort时立即警惕临时表和排序操作!我曾处理过一个报表系统崩溃案例就是这两个标识引发的灾难...
Part2. type列的进阶解密手册
类型 | 速度比较 | 典型场景 |
---|---|---|
system | ★★★★★ | 系统表单记录读取 |
const | ★★★★☆ | 主键等于值匹配(where id=5) |
eq_ref | <ddt/>...
最危险的要属index_merge类型——表面上用了多个索引合并实际上可能是设计失误的信号!上周就碰到where a=1 OR b=2导致性能暴跌的情况...
Part3. rows与filtered的真实含义陷阱
初学时以为rows是精确数值其实这是基于统计信息的估算值!某次线上事故中实际扫描了200万行却显示rows=5000让我们误判风险等级
最近遇到的有趣现象:当Extra出现'Range checked for each record'意味着服务器正在动态评估范围扫描成本 ——这往往发生在复杂join条件中的隐式转换问题上!
Part4. format=JSON后的隐藏彩蛋
开启FORMAT=JSON模式你会看到类似这样的宝藏数据:{"cost_info": {"query_cost": "1.20"}}这时候就能直观比较不同执行方案的代价差异啦~配合ANALYZE TABLE更新统计信息可以获得更准确的预估数据哦!