文章目录
一、开篇暴击:你的SQL正在拖垮整个系统!
最近在排查生产环境性能问题时(说多了都是泪😭),发现一个令人震惊的现象:某个看似简单的查询语句竟然执行了8.3秒! 更可怕的是,这个接口每分钟被调用近千次…(细思极恐啊家人们!)
通过这次血泪教训,我总结了这份《MySQL慢查询优化红宝书》。准备好迎接SQL性能的蜕变了吗?Let’s go!(文末有实战案例,绝对干货!)
二、诊断利器:揪出慢查询的"元凶"
1. 慢查询日志配置(必学操作)
-- 开启慢查询日志(立即生效)
SET GLOBAL slow_query_log = 'ON';
-- 设置慢查询阈值(单位:秒)
SET GLOBAL long_query_time = 1;
-- 查看慢日志存储位置
SHOW VARIABLES LIKE '%slow_query_log_file%';
2. EXPLAIN命令详解(重点中的重点!)
EXPLAIN SELECT * FROM user WHERE age > 18 ORDER BY create_time DESC;
执行结果关键字段解读:
- type列:ALL=全表扫描(立即报警!),index=索引扫描,range=范围扫描
- rows列:预估扫描行数(超过1万行就要警惕)
- Extra列:Using filesort(文件排序警告!),Using temporary(临时表警告!)
三、七大优化神技(实战精华版)
🚀 神技1:索引优化三板斧
- 联合索引最左匹配原则(划重点!)
-- 创建(name,age)联合索引
CREATE INDEX idx_name_age ON user(name, age);
-- 能命中索引的情况
SELECT * FROM user WHERE name = '张三';
SELECT * FROM user WHERE name = '李四' AND age > 20;
-- 无法命中索引的情况 ❌
SELECT * FROM user WHERE age = 25;
- 索引字段禁忌(血的教训!)
- 不在索引列做运算:
WHERE YEAR(create_time) = 2023❌ - 避免使用前导通配符:
WHERE name LIKE '%张%'❌ - 小心NULL值陷阱:
WHERE phone IS NOT NULL❌
💡 神技2:查询语句优化秘籍
分页优化方案对比(数据量百万级时差距惊人!)
| 方案 | 执行时间 | 扫描行数 |
|---|---|---|
| LIMIT 100000,10 | 1.2s | 100010 |
| 延迟关联法 | 0.03s | 20 |
延迟关联具体写法:
SELECT * FROM user u
JOIN (SELECT id FROM user ORDER BY create_time LIMIT 100000,10) AS tmp
ON u.id = tmp.id;
🌟 神技3:架构层面降维打击
- 读写分离架构(QPS提升5倍+)
- 缓存策略组合拳(效果立竿见影!)
- 热点数据:Redis + 本地缓存双保险
- 查询结果缓存:Memcached缓存复杂查询结果
- 缓存击穿解决方案:互斥锁 + 永不过期策略
四、实战案例分析:8秒查询优化到0.02秒
原始问题SQL:
SELECT * FROM orders
WHERE user_id = 12345
AND status = 1
ORDER BY create_time DESC
LIMIT 10;
优化过程全记录:
- EXPLAIN诊断发现:全表扫描,filesort排序
- 创建联合索引:
ALTER TABLE orders ADD INDEX idx_user_status(user_id, status) - 改写SQL语句:
SELECT o.* FROM orders o
JOIN (
SELECT id FROM orders
WHERE user_id = 12345
AND status = 1
ORDER BY create_time DESC
LIMIT 10
) AS tmp ON o.id = tmp.id;
优化效果对比:
- 执行时间:8230ms → 23ms
- 扫描行数:87万 → 10行
- 索引命中率:0% → 100%
五、防坑指南(前人踩坑后人乘凉)
- 隐式类型转换陷阱:
-- user_id是varchar类型时
SELECT * FROM user WHERE user_id = 12345 ❌
-- 应改为
SELECT * FROM user WHERE user_id = '12345' ✅
- OR条件索引失效:
-- 即使name和phone都有索引也会失效!
SELECT * FROM user WHERE name = '张三' OR phone = '13800138000' ❌
-- 优化方案
SELECT * FROM user WHERE name = '张三'
UNION
SELECT * FROM user WHERE phone = '13800138000' ✅
六、性能监控三板斧(7*24小时守护)
-
推荐监控指标:
- 慢查询数量变化曲线
- InnoDB行锁等待时间
- 线程缓存命中率
-
自制监控看板SQL:
-- 实时查看正在执行的慢查询
SELECT * FROM information_schema.processlist
WHERE TIME > 2
AND COMMAND <> 'Sleep'
ORDER BY TIME DESC;
七、终极总结(优化心法口诀)
🔹 索引使用三原则:
建合适的,避无效的,定期维护的
🔹 SQL编写四不要:
不要SELECT *,不要嵌套过深,
不要隐式转换,不要全表扫描
🔹 架构设计两板斧:
读写分离解压力,缓存策略保平安
最后说句掏心窝的话:优化永无止境,但掌握正确方法可以少走80%的弯路!如果觉得有用,赶紧点个收藏⭐,下次遇到性能问题直接照方抓药吧~
1872

被折叠的 条评论
为什么被折叠?



