慢查询日志与优化
2024 年双十一前夜,订单服务的 P99 延迟从 50ms 飙升到 2s。监控告警响成一片,DBA 紧急介入排查。
排查过程:慢查询日志显示,凌晨有一批 ETL 任务跑在高峰期,大量全表扫描的查询把 MySQL 打爆了。
开发同学辩解:"这个查询白天一直跑得好好的,只是今天加了个新字段才变慢的。"
DBA 一看 EXPLAIN,发现这个查询没有命中索引,全表扫描了 5000 万行。
这不是能力问题,是意识问题:没有慢查询日志的意识,没有 EXPLAIN 的习惯,没有索引设计的概念。今天这篇,把 MySQL 慢查询从根上讲透。
一、慢查询日志配置 🔴
1.1 开启慢查询日志
1.2 持久化配置
1.3 慢查询日志内容
关键字段:
- Query_time:查询耗时(秒)
- Lock_time:锁等待时间
- Rows_sent:返回行数
- Rows_examined:扫描行数(核心指标)
⚠️
Rows_examined 是判断查询效率的核心指标。Query_time 长但 Rows_examined 小的,说明服务器资源紧张(锁争用、连接数);Query_time 长且 Rows_examined 大的,说明查询本身需要优化(缺索引)。
二、慢查询分析方法 🟡
2.1 使用 mysqldumpslow 分析日志
2.2 使用 pt-query-digest(推荐)
2.3 EXPLAIN 分析
2.4 ❌ 错误示范
错误 1:只优化 Query_time 最长的查询,不看执行频率。
错误 2:只看 Rows_examined,不看业务意义。
【面试官心理】 这道题我通常会问生产经验。比如:"线上发现一个慢查询,EXPLAIN 显示全表扫描,Rows_examined 是 5000 万,你第一步做什么?"能答出"先看业务影响范围再决定优化优先级"的是有实战经验的人。只知道优化 SQL 的是纯技术思维。
三、索引层面优化 🟡
3.1 建立合适的索引
3.2 避免索引失效
3.3 覆盖索引优化
四、SQL 层面优化 🟡
4.1 避免 SELECT *
4.2 分页深度优化
4.3 批量操作优化
4.4 JOIN 优化原则
五、架构层面优化 🟢
5.1 读写分离
5.2 分库分表
5.3 限制查询范围
【面试官心理】 问慢查询优化的候选人很多,但能说出"架构优化"而不是只盯着 SQL 优化的不多。P7 候选人应该知道:慢查询不只是 SQL 问题,还可能是连接池配置、缓冲池大小、主从延迟等架构问题。