确认 slow_query_log 是否已启用最可靠方式是执行 show variables like 'slow_query_log'; 返回 on 才算真正开启,若为 off 则日志未启用,后续分析无效;同时需检查 long_query_time 和 slow_query_log_file 路径权限。

确认 slow_query_log 是否已启用
直接查变量比猜更可靠:SHOW VARIABLES LIKE 'slow_query_log';。如果返回 OFF,说明日志根本没开,后续所有分析都无从谈起。别依赖“应该开了”这种判断——很多线上库压根没配过,或者配置了但没重启生效。
顺手一起检查:SHOW VARIABLES LIKE 'long_query_time';。MySQL 8.0 默认是 10 秒,对多数业务来说太宽松。电商接口超时通常在 1–2 秒,设成 10 就等于基本不记录;建议先设为 2,上线后根据日志量再调低到 0.5 或 1。
- 临时开启(会话级无效,必须用
GLOBAL):SET GLOBAL slow_query_log = ON; - 但仅执行这句不够——
slow_query_log_file和long_query_time必须同步设,否则可能写到默认路径(如hostname-slow.log),而你根本不知道它在哪 - 注意:
SET GLOBAL修改不持久,MySQL 重启就恢复。生产环境务必写进my.cnf
配置文件里必须写的三项参数
my.cnf 的 [mysqld] 段里,只写这三行就够用,多余参数反而增加维护负担:
[mysqld] slow_query_log = ON long_query_time = 1 slow_query_log_file = /var/log/mysql/slow.log
关键点:
-
slow_query_log_file路径要 MySQL 进程有写权限,常见坑是目录不存在或属主不是mysql用户。用sudo -u mysql touch /var/log/mysql/slow.log测试写入权 - 别加
log_output = FILE,TABLE。写表(mysql.slow_log)会额外消耗连接和锁资源,且日志表默认关闭,还得手动CREATE TABLE,纯属给自己埋雷 -
log_queries_not_using_indexes先别开。它会把全表扫描的查询全记下来,哪怕只查 10 行也记——日志爆炸式增长,掩盖真正耗时的慢查询
日志内容怎么看才不被误导
一条典型日志开头像这样:
# Time: 2026-06-12T07:22:15.123456Z # User@Host: app[app] @ 10.1.2.3 [] # Query_time: 3.214567 Lock_time: 0.000123 Rows_sent: 1 Rows_examined: 98765
重点盯三个数,其他都是干扰项:
-
Query_time:真实执行耗时,超过long_query_time才会被记录——但它不包含网络传输、客户端解析时间,只是服务端执行阶段 -
Rows_examined:扫描行数。如果远大于Rows_sent(比如 10 万扫出 1 行),基本就是缺索引或索引失效,比看Query_time更早暴露问题 -
Lock_time:锁等待时间。如果接近Query_time,说明不是 SQL 本身慢,而是被别的事务堵住了,得去查INFORMATION_SCHEMA.INNODB_TRX
别一上来就优化 Query_time 最高的那条——可能只是个定时任务跑的统计 SQL,而真正卡住用户请求的是另一条 Rows_examined 爆炸但 Query_time 只有 1.2 秒的联表查询。
用 mysqldumpslow 快速筛出真瓶颈
手动翻日志等于大海捞针。mysqldumpslow 是 MySQL 自带的归类工具,不用装额外依赖:
- 先确认存在:
which mysqldumpslow(通常在/usr/bin/或/usr/local/mysql/bin/) - 按总耗时排前 5:
mysqldumpslow -s t -t 5 /var/log/mysql/slow.log - 按扫描行数排前 3(揪出索引问题):
mysqldumpslow -s ar -t 3 /var/log/mysql/slow.log - 过滤特定表:
mysqldumpslow -g "orders" /var/log/mysql/slow.log
输出里最关键的字段是 Count 和 Time。如果某条 SQL Count 高但单次 Time 低,说明是高频轻量查询,可能更适合缓存;如果 Count 低但单次 Time 奇高,优先排查执行计划是否突变(EXPLAIN 对比)。
日志轮转容易被忽略:没配 logrotate 的话,slow.log 几天就能涨到几个 GB,不仅吃磁盘,还会拖慢 mysqldumpslow 解析速度。至少加个每日切割 + 保留 7 天的规则。











