开启慢查询日志是定位卡顿根源的必要动作;常见问题包括long_query_time默认值过高、log_output未指向文件、log_queries_not_using_indexes未启用导致漏记无索引查询,windows下路径转义错误也会导致失败。

直接开慢查询日志不能解决卡顿,但它是定位卡顿根源的必要动作——没它,你只能靠猜。
为什么 set global slow_query_log=ON 后查不到慢 SQL?
常见现象是执行了开启命令,但后续故意跑 SELECT SLEEP(11) 却没在日志里看到记录。原因通常有三个:
-
long_query_time值仍为默认10.000000,而客户端连接可能用了毫秒级精度,实际执行时间略低于 10 秒就逃过了记录(建议临时设为0.1测试) -
log_output被设成了TABLE或NONE,但你只去翻文件;用SHOW VARIABLES LIKE 'log_output'确认当前输出方式 - MySQL 5.6+ 默认不记录未使用索引的查询,如果问题 SQL 恰好走了全表扫描但没超时,它也不会进慢日志——此时要额外开
log_queries_not_using_indexes=ON
Windows 下改 my.ini 后服务起不来?
最常踩的坑是路径里含中文、空格或反斜杠没转义。比如写成 slow_query_log_file="D:mysqllogsmysql-slow.log",Windows 会把 l 当作换行符解析失败。
正确做法是:
- 用正斜杠:
slow_query_log_file="D:/mysql/logs/mysql-slow.log" - 或双反斜杠:
slow_query_log_file="D:\mysql\logs\mysql-slow.log" - 确保
datadir所在磁盘有写权限,且目录logs已手动创建 - 必须包含
log-output=FILE(仅 Windows 显式声明才可靠)
log_queries_not_using_indexes 开了反而日志爆炸?
这个开关一开,所有没走索引的 SELECT 都会被记入,包括 SELECT * FROM users WHERE name = 'admin' 这类本应加索引却漏掉的语句。但它也会把 SELECT COUNT(*) FROM logs(大表无 where)这种合理场景全塞进来,淹没真正耗时的查询。
更务实的做法:
- 先关掉它,用
long_query_time=1抓出明确超时的语句 - 对这些语句逐个
EXPLAIN,看type是否为ALL或index,再针对性加索引 - 真要打开它,务必配合
min_examined_row_limit=1000(只记扫描行数超千的),避免日志被小查询刷屏
慢查询日志本身不优化性能,它只负责诚实暴露问题。最容易被忽略的是:日志里 Rows_examined 和 Rows_sent 的比值——如果前者是后者的几百倍,说明 SQL 在做大量无效扫描,这时候加索引比调 long_query_time 有用得多。











