MySQL slow_query_log / long_query_time 的推荐配置值

6次阅读

开启 slow_query_log 后无日志的最常见原因是未设置 slow_query_log_file,导致日志未落地;需手动指定路径并确保 mysql 进程有写权限,再用 SHOW varIABLES 验证配置。

MySQL slow_query_log / long_query_time 的推荐配置值

slow_query_log 开启后为什么没日志?

最常见原因是 slow_query_log 虽设为 ON,但没指定日志文件路径,MySQL 会默认写入错误日志(error_log)或直接丢弃——尤其在 5.7+ 版本中,若未显式设置 slow_query_log_file,日志可能根本不会落地。

  • 务必手动配置 slow_query_log_file,例如:/var/log/mysql/mysql-slow.log
  • 确认 MySQL 进程对目标路径有写权限(常被忽略,尤其是 systemd 管理的服务,SElinuxappArmor 可能拦截)
  • 执行 SET GLOBAL slow_query_log = ON 后,需用 SHOW VARIABLES LIKE 'slow_query_log'SHOW VARIABLES LIKE 'slow_query_log_file' 双重验证

long_query_time 设多少才合理?

没有通用“推荐值”,取决于你的业务响应预期和数据库负载特征。设得太低(如 0.1s)会导致日志爆炸,设得太高(如 5s)则漏掉大量拖慢用户体验的查询。

  • 线上 OLTP 系统建议从 1.0 开始:覆盖明显慢查询,又不至于淹没日志
  • 并发小事务场景(如电商下单)可收紧到 0.5;报表类从库可放宽至 2.0–5.0
  • long_query_time 是浮点数,支持小数(如 0.3),但注意:MySQL 5.6 及以前只支持秒级整数,升级前先查版本
  • 该阈值仅判断「执行时间」,不包含锁等待、网络传输等,真正卡顿的查询可能因锁争用未达阈值却实际阻塞业务

配合 log_queries_not_using_indexes 用不用?

这个开关会让所有未走索引的 select 都记入慢日志,哪怕执行只花了 0.001s。它对索引治理很有价值,但生产环境要谨慎开启。

  • 只在诊断阶段临时启用(比如上线新表后快速发现缺失索引),避免长期开启——全表扫描的统计类查询、初始化脚本等会大量刷屏
  • 它不记录 INSERT/UPDATE/delete 的索引使用情况,只针对 SELECT
  • 即使开了,也要结合 EXPLaiN 看实际执行计划,因为有些查询看似没走索引,实则是 index_merge 或覆盖索引优化过的

日志轮转和磁盘空间怎么防崩?

MySQL 自身不提供慢日志轮转(logrotate 也不能直接 kill -USR1,因 MySQL 不响应该信号),靠外部工具或定时脚本管理。

  • 不要依赖 FLUSH LOGS 频繁切换文件——它会触发所有日志刷新,可能引发短暂性能抖动
  • 推荐方案:用 logrotate 配合 copytruncate(安全但有极小丢失风险),或用 mv + mysqladmin flush-logs 组合(更可靠,需确保 mv 原子性)
  • 监控 slow_query_log_file 所在分区剩余空间,低于 20% 时告警;单个日志文件超过 500MB 就该介入分析了

慢日志不是开完就完的事,long_query_time 的取值必须和你的应用 P95 响应时间对标,而日志本身只是线索入口——真正关键的是后续用 mysqldumpslowpt-query-digest 抓出 Top SQL,再结合 EXPLAIN ANALYZE 看执行细节。漏掉这步,配置再“合理”也只是摆设。

text=ZqhQzanResources