需同时配置slow_query_log=ON、合理设置long_query_time(如0.5秒)、指定log_output=FILE或TABLE,并用SELECT @@slow_query_log等命令验证生效。

怎么确认慢SQL真的在记录
MySQL 默认不开启慢查询日志,光配了 slow_query_log = ON 不够,还得检查 long_query_time 是否合理(默认是10秒,生产环境通常要调到0.5或1)。更关键的是,log_output 必须设成 FILE 或 TABLE,否则日志根本不会落地——常见错误是只改了开关,忘了输出目标。
-
log_output = FILE:日志写进文件,路径由slow_query_log_file指定,需确保 MySQL 进程有写权限 -
log_output = TABLE:写进mysql.slow_log表,方便用 SQL 查,但会轻微影响性能,且表默认是 CSV 引擎,不支持索引 - 动态开启后,用
SELECT @@slow_query_log和SELECT @@long_query_time立即验证,别只信配置文件
mysqldumpslow 能不能直接用
能,但容易误读结果。它把相似 SQL 归为一类(比如把带不同 ID 的 SELECT * FROM users WHERE id = ? 合并),统计总耗时和次数,适合快速定位“哪类语句最拖”,但看不到具体参数、执行计划或锁等待时间。
- 常用命令:
mysqldumpslow -s t -t 10 /var/lib/mysql/slow.log(按总耗时排序,取前10条模板) - 注意
-g参数可过滤关键词,比如-g "JOIN",但正则能力弱,复杂条件不如 grep 配合 awk 灵活 - 它不解析
SET timestamp或Rows_examined,而这两项对判断是否走索引、是否扫描全表至关重要
pt-query-digest 为什么比自带工具好用
因为它真正把慢日志当“性能事件流”处理:自动提取执行计划、识别重复模式、标注锁等待、聚合 I/O 和 CPU 开销,并生成 HTML 报告。但前提是日志格式得是标准的 MySQL 慢日志(不是 general log,也不是自定义格式)。
- 必须用
--filter过滤掉系统账号或健康检查语句,否则干扰大;例如:--filter '$event->{user} !~ m/^root|monitor/' - 加
--explain参数会让 pt 工具连上库对每条慢 SQL 执行EXPLAIN FORMAT=JSON,但要注意:被解释的 SQL 是“脱敏后还原的”,可能和原始参数不一致 - 报告里
Rows_examined和Rows_sent比值远大于 1,基本等于在扫表;Lock_time高说明锁冲突严重,不是 SQL 本身慢
查到慢SQL后,怎么快速验证优化效果
别急着改索引或重写 SQL,先用 EXPLAIN 对比优化前后执行计划是否真变了。很多“优化”只是让 MySQL 换了个更差的索引,或者触发了隐式类型转换,反而更慢。
- 执行
EXPLAIN FORMAT=JSON,重点看key(实际用的索引)、rows(预估扫描行数)、filtered(过滤率),三者都要变好才算有效 - 如果原 SQL 有
ORDER BY ... LIMIT,注意Using filesort不一定坏——当rows很小,内存排序比走索引回表还快 - 用
SELECT SLEEP(0.1)模拟延迟,配合SHOW PROCESSLIST观察是否还在等锁,避免把并发问题当成单条 SQL 问题
慢 SQL 分析最麻烦的从来不是工具选哪个,而是日志里没记录锁等待、没记录执行计划、也没记录当时并发线程数——这些信息得靠 performance_schema 或第三方 APM 补齐,单靠慢日志只能看到冰山一角。










