手把手教你用EXPLAIN玩转SQL优化(实战经验分享)

一、为什么你的SQL跑得比蜗牛还慢?(灵魂拷问时间)

每次点完查询按钮都要刷会儿手机才能出结果?(真实经历警告⚠️)最近排查线上慢查询时,发现有个同事写的关联查询居然跑了8秒!(表数据才20万条啊喂!)结果用EXPLAIN一看——好家伙,全表扫描+文件排序+临时表三连暴击!(血压上来了)

其实90%的性能问题都能通过执行计划分析定位,今天就带大家把EXPLAIN这个神器玩出花!(文末有超实用速查表)

二、EXPLAIN核心参数全解析(看这一part就够了)

2.1 执行计划身份证(id字段)

-- 举个栗子🌰
EXPLAIN 
SELECT * FROM users u 
JOIN orders o ON u.id = o.user_id
WHERE u.age > 18;

当看到多个相同id值时,说明是同一层级查询(比如联合查询)。数字越大执行优先级越高,NULL表示是UNION后的结果集。

2.2 查询类型盲盒(select_type)

常见类型解析表:

类型出现场景危险指数
SIMPLE简单查询(无子查询/UNION)
PRIMARY外层查询⭐⭐
SUBQUERY子查询⭐⭐⭐
DERIVED派生表(FROM中的子查询)💣
UNION RESULTUNION合并结果⭐⭐

(血泪教训)遇到DERIVED类型要特别注意!之前有个临时表没加索引导致查询直接崩了…

2.3 生死时速type字段(索引使用情况)

性能排序图(建议保存到手机):

system > const > eq_ref > ref > range > index > ALL

举个实战案例:

-- 查询用户最新订单
EXPLAIN
SELECT * FROM orders 
WHERE user_id = 10086 
ORDER BY create_time DESC 
LIMIT 1;

如果type是ref且Extra有"Using filesort",说明虽然用到了索引但排序没走索引,这时候就该考虑(user_id, create_time)的联合索引了!

三、实战优化案例(手撕慢查询)

3.1 案发现场还原

-- 执行耗时:3.8s
SELECT *
FROM products p
LEFT JOIN inventories i ON p.id = i.product_id
WHERE p.category = '电子产品'
AND i.stock > 100
ORDER BY p.price DESC
LIMIT 100;

3.2 EXPLAIN诊断报告

+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | rows    | Extra       |
+----+-------------+-------+------+---------------+------+---------+-------------+
| 1  | SIMPLE      | p     | ALL  | category_idx  | NULL | 200000  | Using where |
| 1  | SIMPLE      | i     | ref  | product_idx   | i    | 5       | Using where |
+----+-------------+-------+------+---------------+------+---------+-------------+

3.3 问题定位

  1. products表全表扫描(type=ALL)
  2. 排序文件排序(Extra没有Using index)
  3. 关联查询没走覆盖索引

3.4 优化三连击

-- ① 添加联合索引
ALTER TABLE products ADD INDEX category_price_idx (category, price);

-- ② 改写查询(使用覆盖索引)
SELECT p.id, p.name, p.price, i.stock 
FROM products p FORCE INDEX(category_price_idx)
INNER JOIN inventories i ON p.id = i.product_id
WHERE p.category = '电子产品'
AND i.stock > 100
ORDER BY p.price DESC
LIMIT 100;

-- ③ 执行计划验证

优化后效果:查询耗时从3.8s → 0.12s!(此处应有掌声👏)

四、EXPLAIN高阶玩法(老司机秘籍)

4.1 JSON格式查看详细执行计划

EXPLAIN FORMAT=JSON 
SELECT ...;

会输出完整的成本估算、访问方式等30+个参数(数据分析师狂喜)

4.2 可视化分析工具

推荐使用MySQL Workbench的Visual Explain功能,自动生成执行流程图:

![图示:可视化执行流程图示例]

(虽然不能放图,但你们想象一下树状结构+各种颜色标注就对了)

4.3 索引失效的7个坑

  1. 隐式类型转换(varchar字段传了int值)
  2. 索引列使用函数(WHERE YEAR(create_time)=2023)
  3. 前导模糊查询(LIKE ‘%手机%’)
  4. OR条件使用不当
  5. 最左前缀原则违反
  6. 数据倾斜严重
  7. 统计信息过期(记得定期ANALYZE TABLE)

五、EXPLAIN速查表(建议打印贴在工位)

参数重点关注值优化方向
type至少达到range级别添加合适索引
rows预估扫描行数超过1万优化查询条件
ExtraUsing filesort/Using temporary调整排序字段或加索引
key_len联合索引使用长度检查索引是否充分利用
filtered低于10%优化WHERE条件选择性

六、写在最后(避坑指南)

最近帮实习生排查一个"索引失效"问题,折腾半天发现——他用的测试库根本没创建索引!(真人真事)所以记住:

  1. 永远要在生产环境相同数据量下验证
  2. 执行计划只是参考,实际耗时可能有波动
  3. 定期使用pt-query-digest分析慢日志
  4. 复杂查询考虑拆分成多个简单查询

下次遇到慢查询别急着甩锅给DBA,自己先掏出EXPLAIN分析一波!(说不定还能在团队分享会上秀一把呢~)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值