必须先确认 slow_query_log 已开启,否则 long_query_time 再小也没用;slow_query_log 默认关闭,未启用时无论阈值设多低都不会记录任何sql,常见失败根源是误以为调了阈值就生效,实则日志开关仍为off。

必须先确认 slow_query_log 已开启,否则 long_query_time 再小也没用。 这是 90% 配置失败的根源——很多人调了阈值却看不到日志,其实是日志开关根本没打开。
为什么设了 long_query_time 却没记录慢 SQL?
常见现象:执行 SELECT SLEEP(2),但 /var/log/mysql/slow.log 仍是空的。原因不是阈值没生效,而是:
-
slow_query_log是 OFF 状态(默认就是 OFF),long_query_time只在日志开启时起作用 - 你用
SET GLOBAL long_query_time = 0.5,但当前会话仍沿用旧值,需额外执行SET SESSION long_query_time = 0.5 - 云数据库(如阿里云 RDS)禁用
SET GLOBAL,必须走控制台或参数模板修改 -
log_output设为TABLE,但mysql.slow_log表不存在、引擎不支持或权限不足
怎么安全地调低 long_query_time 并验证?
别一上来就设 0.1——高并发下日志写入本身会拖慢实例。推荐分步操作:
- 先查真实值:
SELECT @@global.long_query_time;(注意是@@global,不是SHOW VARIABLES) - 临时调低测试:
SET GLOBAL slow_query_log = ON;+SET GLOBAL long_query_time = 2.0; - 触发验证语句:
SELECT SLEEP(2.1);,然后立刻tail -n 1 /var/log/mysql/slow.log - 若用文件输出,确认路径可写:
sudo -u mysql touch /var/log/mysql/slow.log 2>/dev/null && echo ok - MySQL 5.6 及更早版本不支持小数,
0.5会被截断为0,等效于全量记录
哪些 SQL 根本不会进慢日志,即使执行了 10 秒?
默认情况下,INSERT、UPDATE、DELETE 不会被记录,无论多慢。这不是 bug,是设计行为:
- 要捕获写操作,必须显式启用:
SET GLOBAL log_slow_admin_statements = ON; - 该参数也覆盖
ALTER TABLE、ANALYZE TABLE等管理语句,开启前确认你真需要它们 -
log_slow_admin_statements不等于“记录所有 DML”,它只对被 MySQL 视为“管理语句”的写操作生效;更可靠的方式是搭配performance_schema实时抓取 - 锁等待时间(
Lock_time)不计入Query_time,所以一条卡在锁上的SELECT可能不进日志,但实际业务已超时
最易被忽略的一点:日志里 Rows_examined 比 Query_time 更关键——扫 100 万行只返回 1 条,哪怕耗时才 0.2 秒,也是索引缺失的明确信号。











