当你的 MySQL 查询突然变慢,应用响应时间飙升,第一反应往往是查看慢查询日志。但很多人在开启慢查询日志时就卡住了:是临时开启还是写进配置文件?阈值设多少合适?日志文件越来越大怎么办?本文直接围绕这些实际问题,给你一套可操作的排查流程。
慢查询日志是什么,它记录什么
MySQL 的慢查询日志(Slow Query Log)记录了执行时间超过指定阈值(long_query_time)的 SQL 语句,以及未使用索引的查询(如果开启 log_queries_not_using_indexes)。它是定位性能瓶颈的第一手资料。与通用查询日志不同,慢查询日志只关注低效查询,不会记录所有操作,因此对性能影响更小,也更值得长期开启。
如何开启慢查询日志:临时与永久配置
开启慢查询日志有两种方式:临时开启(当前会话或全局)和永久开启(写入配置文件)。
临时开启(适合快速验证)
在 MySQL 命令行中执行:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2; -- 阈值设为 2 秒
SET GLOBAL log_queries_not_using_indexes = 'ON'; -- 可选
注意:long_query_time 的单位是秒,最小可设为 0。设置后需要重新连接或新会话才生效(对于当前会话,可执行 SET SESSION long_query_time = 2)。
永久开启(推荐生产环境)
编辑 MySQL 配置文件(如 my.cnf 或 my.ini),在 [mysqld] 段下添加:
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1
然后重启 MySQL 服务。永久开启的好处是重启后配置依然生效,避免每次手动设置。但要注意日志文件会持续增长,需要定期轮转或清理。
如何确认慢查询日志已生效
开启后,可以通过以下 SQL 检查状态:
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'slow_query_log_file';
SHOW VARIABLES LIKE 'long_query_time';
如果 slow_query_log 为 ON,且文件路径正确,说明已生效。另外,可以故意执行一个耗时超过阈值的查询,然后查看日志文件是否有记录。
慢查询日志分析方法:从原始日志到优化建议
慢查询日志是纯文本文件,每行记录一条慢 SQL 的详细信息,包括执行时间、锁等待时间、返回行数、扫描行数等。直接查看日志文件可以,但数据量大时效率低,推荐使用官方工具 mysqldumpslow 进行汇总分析。
使用 mysqldumpslow 分析
mysqldumpslow 是 MySQL 自带的日志分析工具,可以按执行次数、耗时等排序。常用命令:
mysqldumpslow -s c -t 10 /var/log/mysql/slow.log
该命令按执行次数(c)排序,显示前 10 条。其他排序方式:-s t 按总耗时,-s at 按平均耗时。还可以用 -g 过滤特定模式,例如:
mysqldumpslow -g "SELECT" -s at /var/log/mysql/slow.log
手工分析的关键字段
在原始日志中,每条记录包含类似以下信息:
# Time: 2025-01-01T10:00:00.123456Z
# User@Host: root[root] @ localhost [127.0.0.1]
# Query_time: 2.500000 Lock_time: 0.000100 Rows_sent: 10 Rows_examined: 1000000
SET timestamp=1735704000;
SELECT * FROM orders WHERE customer_id = 12345;
重点关注 Query_time(总执行时间)、Lock_time(锁等待时间)、Rows_examined(扫描行数)和 Rows_sent(返回行数)。如果 Rows_examined 远大于 Rows_sent,说明查询扫描了大量数据,很可能缺少索引或查询写法不佳。
常见误区与注意事项
在开启和分析慢查询日志时,有几个常见误区需要注意:
- 误区一:阈值设置过大或过小。 阈值过大会漏掉很多慢查询,过小则日志量剧增。建议从 2 秒开始,根据业务调整。对于高并发系统,可以设置更小(如 1 秒)。
- 误区二:忽略未使用索引的查询。 开启
log_queries_not_using_indexes可以捕获没有索引的查询,即使执行很快,也可能在大数据量下成为隐患。 - 误区三:日志文件无限增长。 慢查询日志会不断膨胀,需要定期轮转。可以使用 Linux 的 logrotate 工具,或 MySQL 的
FLUSH LOGS命令手动轮转。 - 误区四:只分析日志,不结合执行计划。 慢查询日志只是入口,真正定位问题需要配合
EXPLAIN分析执行计划,检查索引使用情况。
结合其他日志和监控工具
慢查询日志是性能调优的重要依据,但单靠它还不够。建议结合错误日志、通用查询日志,以及监控工具(如 Prometheus + Grafana)进行综合分析。同时,日志记录本身也需要遵循安全规范,避免记录敏感数据(如密码、个人信息),参考 OWASP 日志安全速查表可以帮你设计更安全的日志策略。此外,现代可观测性框架(如 OpenTelemetry)提倡日志、指标、追踪的关联,慢查询日志可以与其他遥测数据结合,提供更完整的性能视图。Python 的 logging 模块虽然面向应用层,但其分层设计思想也适用于理解 MySQL 日志的层级管理。
总结:从开启到分析的完整流程
开启 MySQL 慢查询日志并不复杂,关键是合理配置和分析。总结一下完整流程:
- 确认当前是否已开启:
SHOW VARIABLES LIKE 'slow_query_log'。 - 根据需求设置阈值和文件路径,临时或永久开启。
- 验证生效,并监控日志大小。
- 定期使用 mysqldumpslow 或手工分析,找出高频、高耗时的查询。
- 结合 EXPLAIN 优化索引和 SQL 写法。
记住,慢查询日志不是一次性工具,而是持续监控的一部分。只有长期开启并定期分析,才能及时发现性能退化,避免线上事故。
参考资料
延伸阅读
