慢查询日志需同时满足slow_query_log=on、long_query_time合理设值(如0.2秒)、slow_query_log_file路径可写三条件才生效;仅开开关或阈值未调将导致日志为空,须用select sleep(3)验证写入。

慢查询日志不是“开了就灵”的开关,必须同时满足 slow_query_log = ON、long_query_time 合理设值、slow_query_log_file 路径可写这三项,否则日志根本不会落盘——线上查不到慢 SQL,90% 是卡在这一步。
确认 slow_query_log 和 long_query_time 是否真正配对生效
只设 slow_query_log = ON 但没动 long_query_time,日志照样为空。MySQL 5.7+ 默认阈值是 10 秒,而现代 OLTP 场景下,200ms 就可能暴露锁争用或索引失效问题。
-
SET GLOBAL slow_query_log = ON和SET GLOBAL long_query_time = 0.2必须成对执行,且仅对新连接生效;当前会话需重新登录或执行SELECT @@long_query_time验证 - 生产环境推荐从
long_query_time = 2.0起步,观察Slow_queries计数和磁盘 I/O 压力,再逐步下调 - 注意:5.7+ 版本中
long_query_time仍按秒比较,但内部计时精度为微秒;设0.9在旧版本可能被截断为 0,导致全量记录 - 验证是否真在写入:别只信
SHOW VARIABLES LIKE 'slow_query_log',要立刻跑SELECT SLEEP(3)(确保 ≥ 当前阈值),再tail -n 1 /var/log/mysql/slow.log
slow_query_log_file 路径与权限常被忽略
路径不存在、属主不是 mysql 用户、SELinux 拦截,都会让日志静默失败——错误日志里往往只有 Could not write to slow log 这一条线索。
- 路径必须是绝对路径,如
/var/log/mysql/slow.log,不能是相对路径或 MySQL 数据目录子路径(如./slow.log) - 创建目录并赋权:
mkdir -p /var/log/mysql && chown mysql:mysql /var/log/mysql - 云数据库(如阿里云 RDS)可能屏蔽
SET GLOBAL或覆写配置,必须进控制台确认「慢日志开关」和「阈值」是否真正启用 - 若用容器部署,确保挂载卷有写权限,且
slow_query_log_file指向容器内可写路径(如/var/log/mysql/而非/data/)
log_queries_not_using_indexes 不是“加了更安全”,而是双刃剑
它能捕获“快但危险”的全表扫描语句(比如 SELECT COUNT(*) FROM config),但极易引发日志刷屏,尤其在高频小查询场景。
- 必须搭配
log_throttle_queries_not_using_indexes使用,例如SET GLOBAL log_throttle_queries_not_using_indexes = 3,限制每秒最多记录 3 条 - 设
long_query_time ≤ 0.5时,建议关闭log_queries_not_using_indexes,否则日志体积暴涨且干扰主线分析 - 它不记录 DML(
UPDATE/DELETE)的索引使用情况,这类语句是否走索引,得靠EXPLAIN或performance_schema.events_statements_summary_by_digest - 该选项在 Percona Server 和 MariaDB 中行为更稳定,MySQL 官方版 8.0+ 对其支持已趋成熟,但默认仍不开启
分析日志时别只盯 Query_time,Rows_examined 才是索引健康度晴雨表
一条 Query_time: 0.08 的 SQL 可能比 Query_time: 1.2 更危险——如果它 Rows_examined: 1240000 却只 Rows_sent: 1,说明索引完全没生效或设计错位。
- 重点关注
Rows_examined / Rows_sent比值:>100 就该怀疑索引缺失,>1000 基本确定要优化 -
Lock_time高但Query_time低?说明瓶颈不在 SQL 执行本身,而在行锁/表锁等待,需查information_schema.innodb_lock_waits -
mysqldumpslow解析多行 SQL 或带毫秒精度日志时容易出错,推荐改用pt-query-digest,命令如:pt-query-digest /var/log/mysql/slow.log --limit 10 - 日志中出现
# User@Host但无具体 SQL?可能是客户端断连或语句被截断,检查max_allowed_packet是否过小
最易被跳过的环节是:没验证日志文件实际内容,就直接去分析;或者把 long_query_time 设得过低,却忘了关 log_queries_not_using_indexes,结果磁盘被日志撑爆。真实线上环境里,慢日志的价值不在于“抓得多”,而在于“抓得准”。











