应执行show variables like 'slow_query_log',返回on才真正启用;若为off则未开启,即使my.cnf已配置也无效,需重启mysql或执行set global slow_query_log = on。

如何确认慢查询日志当前是否启用
直接查 slow_query_log 变量值最可靠,别只看配置文件有没有写。执行:
SHOW VARIABLES LIKE 'slow_query_log';如果返回
OFF,说明没开,哪怕 my.cnf 里写了也白搭——MySQL 启动时加载失败或被运行时命令覆盖了。常见误判点:有人改完 my.cnf 就以为生效,其实必须重启 MySQL 或执行 SET GLOBAL slow_query_log = ON;(后者需有 SUPER 权限,且实例重启后失效)。
设置慢查询阈值用 long_query_time 要注意单位和精度
long_query_time 单位是秒,支持小数,比如设成 0.5 表示记录超过 500ms 的语句。但要注意:MySQL 5.7+ 默认使用微秒级计时,而该变量仍以秒为单位显示;实际判断时会四舍五入到最接近的微秒,所以设 0.01 并不严格等于 10ms,可能略高或略低。
建议操作:
- 线上环境先设保守值,比如
2秒,观察日志量,再逐步下调 - 避免设
0—— 这会让所有 SQL 都记日志,I/O 压力陡增,甚至拖垮实例 - 用
SELECT @@long_query_time;查当前生效值,注意它可能是会话级覆盖过的
日志输出位置由 slow_query_log_file 和 log_output 共同决定
只配 slow_query_log_file 不够。MySQL 支持把慢日志写进文件(FILE)或写进表 mysql.slow_log(TABLE),由 log_output 控制。默认是 FILE,但若你执行过 SET GLOBAL log_output = 'TABLE';,那即使指定了 slow_query_log_file 路径,日志也不会落地成文件。
检查方法:
SHOW VARIABLES LIKE 'log_output';<br>SHOW VARIABLES LIKE 'slow_query_log_file';如果想确保写文件,运行:
SET GLOBAL log_output = 'FILE';,再确认 slow_query_log_file 指向的目录 MySQL 进程有写权限(常见坑:目录属主是 root,MySQL 是 mysql 用户,导致日志创建失败且无报错)。分析慢日志不能只靠 mysqldumpslow 看 topN
mysqldumpslow 是个快速入口,但它的聚合逻辑会丢失关键上下文:比如相同 SELECT * FROM t WHERE id = ? 被聚成一条,但实际参数不同,可能一个是命中索引,一个是全表扫描。真正定位问题得结合原始日志里的 # Query_time、# Lock_time、# Rows_sent、# Rows_examined 四项数据看效率比。
实操建议:
- 用
grep -A 2 "Query_time.*[1-9]\.[0-9]\+" /var/lib/mysql/xxx-slow.log快速抓出耗时 >1s 的原始记录 - 重点看
Rows_examined是否远大于Rows_sent—— 这通常意味着没走对索引或存在隐式转换 - 注意日志里带
# Time:的时间戳是语句执行完成时间,不是开始时间,排查时序问题要小心
慢查询日志本身不记录执行计划,要验证优化效果,得对具体 SQL 手动跑 EXPLAIN;日志里也没有客户端 IP 和账号信息(除非开启 log_slow_admin_statements 或用代理层补全),权限类问题得另想办法追溯。











