必须检查slow_query_log、long_query_time和slow_query_log_file配置是否生效,生产建议long_query_time设为1或0.5,并启用log_queries_not_using_indexes定位隐性索引问题。

确认慢查询日志是否真的在记录
很多人以为开了 slow_query_log = ON 就万事大吉,结果查日志文件发现空空如也——最常见原因是 long_query_time 还是默认的 10 秒,而实际慢 SQL 往往卡在 1~2 秒。必须先验证:登录 MySQL 后执行
SHOW VARIABLES LIKE 'slow_query_log';<br>SHOW VARIABLES LIKE 'long_query_time';<br>SHOW VARIABLES LIKE 'slow_query_log_file';
如果 slow_query_log 是 OFF,或 long_query_time ≥ 5,那基本看不到有效记录。生产环境建议设为 1 或 0.5(支持小数),并确保 slow_query_log_file 路径的目录存在、MySQL 进程有写权限(比如 /var/log/mysql/ 下需 chown mysql:mysql)。
直接查看日志文件内容
慢查询日志是纯文本,不用解析工具也能读。但要注意两点:一是日志路径可能不是你想象的位置(默认可能是 /var/lib/mysql/hostname-slow.log);二是 MySQL 重启后日志文件名可能带时间戳或主机名变化。常用查看方式:
-
tail -f /var/log/mysql/mysql-slow.log—— 实时追加,适合刚配好时验证是否真有记录 -
less /var/log/mysql/mysql-slow.log—— 支持搜索(按/键输入Query_time可快速定位慢条目) - 每条记录含
Query_time、Rows_examined、SQL语句本身——重点看后者是否用了索引、是否LIKE '%xxx%'全模糊、是否ORDER BY没走索引
用 mysqldumpslow 快速抓重点
手动翻几百行日志效率低,mysqldumpslow 是 MySQL 自带的聚合分析工具,它不分析单条,而是把相似 SQL 归类统计。典型用法:
-
mysqldumpslow -s at -t 5 /var/log/mysql/mysql-slow.log—— 找平均耗时 top 5 的 SQL(-s at中at= average time) -
mysqldumpslow -s c -t 10 /var/log/mysql/mysql-slow.log—— 找执行次数最多的 10 条(高频但未必慢,可能是没缓存的重复查询) -
mysqldumpslow -g "SELECT.*users" /var/log/mysql/mysql-slow.log—— 正则过滤含 users 表的慢查询
注意:mysqldumpslow 需要 Perl 环境,某些精简版 Docker 镜像里没有,会报 Can't locate Getopt/Long.pm,此时得进容器装 perl 或改用其他方式。
别漏掉“快但没走索引”的查询
很多性能隐患藏在 Query_time 很短(比如 0.02 秒)、但 Rows_examined 却高达几十万的 SQL 里——这说明它没走索引,靠全表扫描硬扛。这类 SQL 默认不会进慢日志,除非你显式开启:
- 临时启用:
SET GLOBAL log_queries_not_using_indexes = 'ON'; - 永久配置:在
my.cnf的[mysqld]段加log_queries_not_using_indexes = 1
开启后,哪怕一条 SELECT * FROM orders WHERE status = 'pending' 只花 0.01 秒,只要 status 没索引,也会被记入日志。这是定位隐性瓶颈的关键开关,但别长期开着——它会让日志量暴增,尤其在数据量大的表上。











