文章目录
目录
- 血泪教训:我的第一个生产事故
- 慢查询日志:抓住元凶的刑侦手段
- 执行计划分析:SQL的X光透视
- 索引优化:给数据库装上涡轮增压
- SQL重构:手术刀级别的代码改造
- 参数调优:容易被忽略的隐藏Buff
- 缓存策略:最后一公里的冲刺
- 实战成果:性能提升100倍
1. 血泪教训:我的第一个生产事故
去年双十一凌晨2点,我正美滋滋吃着宵夜(炸鸡真香!),突然收到监控告警——核心订单接口响应时间突破天际!页面加载直接卡在10秒以上(用户估计要骂娘了…)
用SHOW PROCESSLIST
一看,发现有个统计报表的SQL执行了整整58秒!更可怕的是这个查询每分钟被执行20多次,直接把数据库CPU干到100%。最后不得不临时kill掉这些慢查询,结果报表数据延迟了3小时(被老板请去喝茶的酸爽你懂的)
2. 慢查询日志:抓住元凶的刑侦手段
(必看)开启慢查询日志的正确姿势:
-- 这个配置能救命!
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1; -- 超过1秒的都记录
SET GLOBAL log_queries_not_using_indexes = ON; -- 抓出没走索引的坏分子
分析工具推荐:
mysqldumpslow
(官方自带)- pt-query-digest(神器!能生成超详细的报告)
- 阿里云DAS的SQL分析功能(云数据库用户的福音)
3. 执行计划分析:SQL的X光透视
遇到慢SQL千万别急着改!先用EXPLAIN
看看执行计划(这是老司机的必修课)
关键指标解读:
- type列:ALL全表扫描直接判死刑!
- rows列:扫描行数超过1万就要警惕
- Extra列:出现
Using filesort
或Using temporary
马上拉响警报
4. 索引优化:给数据库装上涡轮增压
我的翻车现场:
曾经给user表
的status
字段加索引,结果查询更慢了?!后来发现这个字段只有0/1两种值,区分度太低根本不适合建索引(啪啪打脸)
正确索引姿势:
- 联合索引遵循最左前缀原则
- 区分度高的字段放前面
- 避免在索引列做计算:
WHERE YEAR(create_time)=2023
→ 索引失效! - 小心隐式类型转换:
WHERE phone=13800138000
(phone是varchar类型) → 全表扫描!
神奇案例:
有个统计查询从8秒降到0.2秒,仅仅是把SELECT *
改成了SELECT id,name
(覆盖索引YYDS!)
5. SQL重构:手术刀级别的代码改造
经典优化套路:
- 大分页优化:不要用
LIMIT 100000,10
,改用WHERE id > 100000 LIMIT 10
- **拒绝SELECT ***:查询字段多1个,性能可能差10倍!
- 拆解复杂查询:把1个关联查询拆成2个简单查询+程序处理
- 巧用延迟关联:
-- 优化前
SELECT * FROM orders WHERE user_id=123 ORDER BY id LIMIT 100000,10
-- 优化后
SELECT * FROM orders
INNER JOIN (SELECT id FROM orders WHERE user_id=123 ORDER BY id LIMIT 100000,10) AS tmp
USING(id)
6. 参数调优:容易被忽略的隐藏Buff
关键参数配置(适用于MySQL 8.0+):
innodb_buffer_pool_size = 物理内存的70% # 缓存池是性能命门!
join_buffer_size = 4M # 不要无脑调大!
sort_buffer_size = 4M # 每个连接单独分配,小心OOM
max_connections = 500 # 根据实际情况调整
thread_cache_size = 32 # 减少线程创建开销
血泪教训:
曾经把join_buffer_size
从256K调到2G,结果数据库直接OOM崩溃!调参一定要循序渐进。
7. 缓存策略:最后一公里的冲刺
当SQL优化到极致还想提升?上缓存!
多级缓存方案:
- MySQL查询缓存(注意!8.0+已移除)
- 应用层缓存:Redis/Memcached
- ORM缓存:MyBatis二级缓存
- 本地缓存:Caffeine/Guava Cache
缓存三大灵魂拷问:
- 缓存一致性怎么保证?
- 缓存穿透/雪崩/击穿如何预防?
- 热点数据发现机制是否完善?
8. 实战成果:性能提升100倍
经过上述组合拳优化,那个58秒的统计SQL最终降到0.05秒!优化过程总结:
- 定位问题:慢查询日志+执行计划分析
- 索引改造:添加复合索引+覆盖索引
- SQL重构:拆分子查询+避免filesort
- 参数调优:调整join_buffer_size
- 缓存加持:Redis缓存统计结果
优化后的EXPLAIN结果对比:
总结
慢SQL优化就像破案,需要:
- 精准定位问题(慢查询日志)
- 深入分析证据(执行计划)
- 合理使用工具(索引、参数、缓存)
- 勇于推翻重来(SQL重构)
记住:没有最好的优化方案,只有最适合业务场景的方案!下次遇到性能问题,希望你能笑着面对(而不是像我一样被老板请喝茶…)
#MySQL优化 #慢查询 #SQL调优 #数据库性能 #索引优化