【Java 开发日记】我们来说一下 MySQL 的慢查询日志
作为Java后端开发,慢查询日志(Slow Query Log)大概是我们最常用来排查线上数据库性能瓶颈的利器之一。
很多时候接口超时、CPU/IO飙高、数据库连接堆积,最终追到根上,十有八九都能在慢查询日志里找到“真凶”。
今天我们从零到一完整过一遍:什么是慢查询、怎么开、怎么配、怎么看、怎么分析、怎么优化,MySQL 8.0+ 的最新实践(2025-2026 年仍然适用)。
1. 什么是慢查询日志?
慢查询日志会记录所有执行时间超过阈值的 SQL 语句(包括 SELECT、UPDATE、INSERT、DELETE 等),帮助我们快速定位耗时 SQL。
关键判断条件(必须同时满足):
- 执行时间 ≥
long_query_time(单位:秒) - 检查过的行数 ≥
min_examined_row_limit(默认 0) - 如果开启
log_queries_not_using_indexes,即使没超时但没走索引的查询也会被记录(非常推荐!)
2. 核心配置参数一览(MySQL 8.0+)
| 参数 | 默认值 | 说明 | 推荐生产值 |
|---|---|---|---|
| slow_query_log | OFF | 是否开启慢查询日志,总开关 | ON |
| slow_query_log_file | hostname-slow.log | 日志文件路径(建议放到单独磁盘,避免和数据盘争 IO) | /data/mysql/slow.log |
| long_query_time | 10.000000 | 慢查询阈值(秒),可小数 | 0.5 ~ 2(视业务) |
| log_queries_not_using_indexes | OFF | 是否记录未使用索引的查询(即使没超时) | ON(强烈推荐) |
| min_examined_row_limit | 0 | 至少扫描多少行才算慢查询 | 1000 或更高(视情况) |
| log_output | FILE | 输出方式:FILE / TABLE / FILE,TABLE | FILE(性能更好) |
| log_slow_admin_statements | OFF | 是否记录慢的 DDL(如 ALTER TABLE) | ON(视需求) |
3. 怎么开启慢查询日志?(两种方式)
方式一:临时开启(重启失效,适合测试/临时排查)
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1; -- 1秒
SET GLOBAL log_queries_not_using_indexes = 'ON';
SET GLOBAL slow_query_log_file = '/data/mysql/slow.log';
方式二:永久生效(推荐生产)
修改配置文件(my.cnf / my.ini),加到 [mysqld] 段下:
[mysqld]
slow_query_log = ON
slow_query_log_file = /data/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = ON
min_examined_row_limit = 1000
log_output = FILE
# 可选:记录慢的DDL
log_slow_admin_statements = ON
然后重启 MySQL,或者执行 SET GLOBAL ... 后配合 FLUSH SLOW LOGS; 刷新。
4. 怎么查看慢查询日志内容?
慢查询日志长这样(MySQL 8.0+ 格式):
# Time: 2026-01-12T17:15:23.456789Z
# User@Host: order_user[order_user] @ [10.20.30.45] Id: 98765
# Query_time: 3.245678 Lock_time: 0.000456 Rows_sent: 1 Rows_examined: 8456789
# Rows_affected: 0
SET timestamp=1736702123;
SELECT * FROM orders
WHERE create_time > '2025-12-01'
AND status = 'PAID'
ORDER BY id DESC
LIMIT 20;
关键字段含义:
- Query_time:真正执行耗时(最重要!)
- Lock_time:等待锁的时间
- Rows_examined:扫描了多少行(越大越危险)
- Rows_sent:最终返回多少行
5. 怎么高效分析慢查询日志?(生产必备工具)
手动翻日志基本不可能,推荐以下组合拳:
- mysqldumpslow(MySQL 自带,最轻量)
# 按执行时间排序,显示前10条
mysqldumpslow -s t -t 10 /data/mysql/slow.log
# 按扫描行数排序
mysqldumpslow -s r -t 20 /data/mysql/slow.log | more
# 加上 grep 筛选特定表
mysqldumpslow -s t -t 10 /data/mysql/slow.log | grep "FROM orders"
- pt-query-digest(Percona Toolkit 神器,强烈推荐)
pt-query-digest /data/mysql/slow.log > digest.txt
它会给你汇总:
- 总次数、总耗时、平均耗时
- 95% 响应时间
- 出现频率最高的 SQL 模板
- 指纹化(自动把参数替换成?)
- 云厂商控制台(阿里云 DAS、腾讯云、AWS RDS 等)
基本都自带可视化慢查询分析 + 一键优化建议,极大降低分析成本。
6. 生产环境最佳实践建议(2025-2026 版)
- 阈值建议:高并发系统建议从 1秒 开始,逐步降到 0.3~0.5秒
- 一定要开
log_queries_not_using_indexes=ON—— 很多全表扫的 SQL 其实没超时,但隐患极大 - 日志文件单独磁盘,最好用 SSD
- 定期轮转 + 清理(logrotate 或 cron 任务)
- 慢查询 → EXPLAIN → 加索引 → 改写 SQL → 引入缓存/读写分离 的完整闭环
- 配合 performance_schema + sys schema 做更深度的诊断
- 高峰期可临时把 long_query_time 调小(如 0.1s)采集 10~30 分钟,然后恢复
小结一句话
慢查询日志不是用来“看”的,而是用来“治”的。
发现 → 分析 → 优化 → 验证 → 监控告警,形成闭环,才是 Java 开发 + DBA 联手把数据库性能盘活的正确姿势。
下次遇到线上卡顿,先问一句:
“慢查询日志开了吗?最近的 Top10 慢 SQL 是什么?”
有需要的同学可以把你们公司的慢查询阈值和最常见的慢 SQL 类型评论区交流一下~
下篇可以聊聊 如何结合 Explain + 索引实战优化 Top10 慢查询,有兴趣的点个赞提醒我继续写哈~ 😄