先确认slow_query_log=on、long_query_time设为0.5~1、log_queries_not_using_indexes=on;再用mysqldumpslow结合count/time/lock/rows_examined分析;最后通过pt-query-digest归一化+explain关注key、rows、extra及query_cost。

慢查询日志里查不到“真凶”SQL?先确认这三件事
直接查 slow_query_log_file 却找不到高 CPU 或高 IO 的 SQL,大概率是配置没生效,或阈值设得太高。别急着分析日志内容,先验证基础是否可靠:
-
slow_query_log必须为ON(不是1,MySQL 8.0+ 只认字符串值) -
long_query_time默认是 10 秒,对线上系统基本无效;建议设为0.5或1,尤其在 SSD 环境下 -
log_queries_not_using_indexes设为ON很关键——很多“快但伤库”的 SQL(比如全表扫描返回 1 行)根本达不到long_query_time,但会大量消耗 buffer pool 和 CPU
改完记得执行 SET GLOBAL slow_query_log = ON(如果动态生效),再用 SHOW VARIABLES LIKE 'slow_query_log%' 确认实际值。
mysqldumpslow -t10 -s t 输出结果里,哪些字段真正反映资源消耗?
mysqldumpslow 默认按平均查询时间(-s t)排序,但这和“资源消耗大”不是一回事。真正要盯的是这三项:
-
Count:执行次数。高频低耗 SQL(如简单主键查)可能总耗时不高,但会挤占连接、触发频繁刷脏页 -
Time(总耗时)+Lock(锁等待时间):如果Lock占比超过 30%,说明是锁争用瓶颈,不是 SQL 本身慢 -
Rows_examined:扫描行数。比Rows_sent更重要——100 万行扫描只返回 1 行,就是典型索引缺失或条件未走索引
常用组合:mysqldumpslow -t20 -s al slow.log(按平均锁等待排),或 mysqldumpslow -t20 -s c slow.log(按执行次数排),再人工过滤出 Rows_examined 异常高的条目。
为什么同一个 SQL 在 slow.log 里出现多次,却看不出共性?
因为原始日志记录的是字面 SQL,SELECT * FROM orders WHERE user_id = 123 和 SELECT * FROM orders WHERE user_id = 456 被当两条独立语句。靠人工翻日志根本没法聚类。
正确做法是启用 log_slow_verbosity = 'full'(MySQL 5.7.2+),它会让慢日志自动带 Query_time、Lock_time、Rows_sent、Rows_examined,更重要的是——开启 log_slow_filter 配合 pt-query-digest 工具做指纹归一化:
pt-query-digest --filter '$event->{Rows_examined} > 1000' /var/lib/mysql/slow.log- 输出里
Query_class列就是归一化后的模板,比如SELECT * FROM orders WHERE user_id = ? - 看
Rank和Response time总耗时,再结合Rows_examined_total判断是否该加索引
查到 Top SQL 后,EXPLAIN 看什么才不跑偏?
别只盯着 type 是不是 ALL 或 index。真正决定资源消耗的是这三点:
-
key为空,但possible_keys有值 → 索引存在但没被选中,可能是统计信息过期(ANALYZE TABLE)或隐式类型转换(比如WHERE phone = 13800138000,phone 是 VARCHAR) -
rows远大于实际返回行数(比如rows=100000但Extra显示Using where; Using filesort)→ 查询条件没有效过滤,ORDER BY 又没走索引,会建临时表 + 排序 -
Extra出现Using temporary或Using filesort→ 基本等于内存/磁盘开销大户,优先优化
注意:EXPLAIN FORMAT=JSON 比传统格式多一个 query_cost 字段,它综合了 IO 和 CPU 预估,比单纯看 rows 更接近真实资源消耗。
慢查询日志只是入口,真正的资源消耗判断必须交叉验证:日志里的 Rows_examined、Performance Schema 里的 TIMER_WAIT、OS 层的线程 CPU 使用率——三者指向同一 SQL,才值得动刀优化。











