文章目录
还在对着慢查询日志发呆?还在用玄学方法优化SQL?今天带你解锁MySQL自带的「X光透视仪」——EXPLAIN命令!(这才是DBA真正的吃饭家伙)
一、这个命令到底有多神奇?(小白必看)
在终端输入EXPLAIN + 你的SQL语句
,MySQL就会把执行计划摊开给你看!(就像给SQL做CT扫描)哪些步骤在偷懒?哪些索引没生效?全给你扒得明明白白!
举个栗子🌰:
EXPLAIN SELECT * FROM users WHERE age > 25 ORDER BY created_at DESC;
执行后你会看到这样的表格:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 956 | Using where; Using filesort |
(看到那个刺眼的ALL了吗?这就是全表扫描的罪证!!)
二、十一个关键字段全解析(DBA面试必考)
1. id字段:SQL执行顺序图
- 数字越大越先执行(划重点)
- 相同id按从上到下顺序执行
- 带
<subquery>
的是子查询
2. select_type:查询类型大全
- SIMPLE:简单SELECT(不包含子查询或UNION)
- PRIMARY:最外层查询(就像董事长)
- DERIVED:派生表(FROM子句中的子查询)
- DEPENDENT SUBQUERY:相关子查询(性能杀手!)
3. type字段:性能红黑榜
(性能从好到坏排序)
- system:系统表(完美)
- const:通过主键访问(优秀)
- eq_ref:唯一索引关联(良好)
- ref:普通索引查询(及格)
- range:范围扫描(要警惕)
- index:全索引扫描(危险)
- ALL:全表扫描(立即优化!!!)
4. Extra字段暗藏玄机
- Using filesort:文件排序(内存或磁盘)
- Using temporary:创建临时表(立即优化)
- Using index:覆盖索引(优秀)
- Using where:需要回表查询
三、实战案例分析(手把手教学)
案例1:索引失效惨案
某订单表查询突然变慢:
EXPLAIN SELECT * FROM orders WHERE YEAR(create_time) = 2023;
结果:
type: ALL
key: NULL
Extra: Using where
诊断报告:因为对字段做了函数运算,导致索引失效!(解决方案:改为create_time BETWEEN '2023-01-01' AND '2023-12-31'
)
案例2:联合索引翻车现场
用户表查询:
EXPLAIN SELECT * FROM users
WHERE age > 18
AND city = '北京'
ORDER BY create_time DESC;
现有索引:INDEX(age,city)
执行计划:
type: range
key: age_city_index
Extra: Using index condition; Using filesort
问题定位:排序字段不在索引中,导致filesort(解决方案:改为联合索引(age,city,create_time)
)
四、高级技巧大放送(老司机秘籍)
-
EXPLAIN ANALYZE(MySQL 8.0+专属):
EXPLAIN ANALYZE SELECT * FROM products WHERE price > 100;
会显示实际执行时间!(比普通EXPLAIN更准)
-
JSON格式输出:
EXPLAIN FORMAT=JSON SELECT ...;
包含更详细的信息(连成本估算都有)
-
可视化工具推荐:
- MySQL Workbench执行计划可视化
- Percona Toolkit的pt-visual-explain
- 在线工具:https://explain.dalibo.com/
五、避坑指南(血泪教训)
- 不要只看type字段:即使type是ref,如果rows值很大也很危险
- 警惕Using temporary:临时表可能撑爆内存
- 注意key_len长度:可以判断联合索引使用了多少列
- 关注filtered列:表示存储引擎返回的数据在server层过滤的比例
- 定期检查执行计划:数据量变化可能导致索引失效
六、性能优化组合拳
- 先用EXPLAIN定位问题
- 调整索引策略(覆盖索引最香)
- 重写SQL语句(避免函数转换)
- 调整服务器参数(适当增加sort_buffer_size)
- 考虑业务逻辑优化(加缓存/异步处理)
最后说两句(老师傅的忠告)
曾经有个500万行的表查询要8秒,用EXPLAIN一看——type是index,Extra有Using filesort。把ORDER BY字段加到索引后,0.2秒搞定!这工具用好了,真的是事半功倍!!!
(下次面试被问SQL优化,先把EXPLAIN的字段背熟,保证惊艳面试官!)