必须同时满足全局开关为ON、日志路径可写、long_query_time设置合理、有新连接触发执行四个条件,否则日志为空;验证需查变量值、路径权限及Slow_queries计数是否增长。

慢查询日志不是“开了就能用”,必须同时满足四个条件:全局开关为 ON、日志路径可写、long_query_time 设置合理、且有新连接触发执行——缺一不可,否则日志文件永远为空。
确认 slow_query_log 是否真正生效(不是只看配置)
很多人改完配置就以为万事大吉,结果日志没内容。关键要验证三件事:
-
SHOW VARIABLES LIKE 'slow_query_log'返回值必须是ON(不是1或空字符串) -
SHOW VARIABLES LIKE 'slow_query_log_file'显示的路径,MySQL 进程必须有写权限(XAMPP 下注意 Windows UAC 拦截 C:\ 根目录) -
SHOW GLOBAL STATUS LIKE 'Slow_queries'初始为0,执行SELECT SLEEP(2)后必须变成1,否则说明日志逻辑根本没走通
特别注意:slow_query_log 是只读全局变量,对已有连接无效。即使你刚执行了 SET GLOBAL slow_query_log = 'ON',也得新开一个命令行连接(或重启客户端)才能生效。
long_query_time 设多少才不漏不爆
这个值不是越小越好,它直接决定日志量和问题覆盖度:
- 线上建议从
1.0秒起步,观察 1–2 小时日志量和典型耗时分布,再决定是否下调 - 设成
0.5时,MySQL 5.7 只保留一位小数(如 0.498s 记为 0.4s),可能漏掉真实慢查询;8.0+ 支持微秒但需配合log_slow_extra=ON -
long_query_time只统计 SQL 执行时间,不含锁等待、网络传输、连接排队——所以Query_time: 0.8+Lock_time: 1.2的语句,实际卡在锁上,不是 SQL 本身 - 绝对不要设
0:会记录所有查询(包括SELECT 1),磁盘 IO 和文件体积瞬间失控
log_queries_not_using_indexes 不是“开就完事”
开启它确实能发现索引缺失,但代价是大量噪音:
- 哪怕
WHERE id = -1这种恒不命中、只扫描 1 行的查询也会被记录 - 必须同步设置
min_examined_row_limit = 100(或更高),表示“未走索引且扫描行数 ≥ 100 才记”,否则日志里全是干扰项 - 该参数不能动态修改(MySQL 5.7+ 部分版本支持,但云厂商常禁用),必须写进
my.cnf并重启 MySQL - 调试阶段建议先关掉
log_queries_not_using_indexes,等定位到具体慢 SQL 后,再针对性检查是否走索引
分析日志前必须盯住三行字段
别急着扔给 mysqldumpslow,先人工扫一遍开头几条记录:
-
# Query_time:看真实耗时,注意单位:5.7+ 是秒带小数(1.234567),老工具可能截断解析失败 -
# Lock_time:如果接近Query_time,瓶颈在锁争用,不是 SQL 或索引问题 -
Rows_examined:和Rows_sent:对比——扫了 50 万行只返回 3 行?那一定是索引没用上或条件没下推
真正容易被忽略的是:日志里记录的 Query_time 不包含查询被连接池排队的时间,也不含应用层网络延迟。如果接口超时但慢日志里找不到对应 SQL,大概率是请求在到达 MySQL 前就卡住了。



















