HOOOS

手把手教你读懂MySQL执行计划的奥秘

0 53 SQL调优工程师 MySQL优化执行计划解读数据库调优
Apple

当我第一次在控制台敲下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列的进阶解密手册

<ddt/>
...
类型速度比较典型场景
system★★★★★系统表单记录读取
const ★★★★☆主键等于值匹配(where id=5)
eq_ref

最危险的要属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更新统计信息可以获得更准确的预估数据哦!

点评评价

captcha
健康