在数据库运维和性能调优工作中,慢查询日志(Slow Query Log)是我们最常用的诊断工具之一。它能够帮助我们快速定位那些执行效率低下的SQL语句,为后续优化提供精准的切入点。本文将带你从零开始,全面了解MySQL慢查询日志的配置、使用及分析方法。
📌 什么是慢查询日志?
慢查询日志 是MySQL提供的一种记录机制,用于记录所有执行时间超过预设阈值(long_query_time)的SQL语句,以及未使用索引的查询语句。它就像数据库的"体检报告",能直观展示哪些查询拖慢了系统性能。
默认情况下,慢查询日志功能是关闭 的,需要手动开启。日志可以存储在文件 (FILE)或数据库的专用表(TABLE)中,方便后续分析。
⚙️ 慢查询相关参数详解
在开启慢查询前,我们先了解几个核心参数:
| 参数名 | 说明 |
|---|---|
slow_query_log |
是否开启慢查询日志,值为 ON / OFF |
slow_query_log_file |
慢查询日志的存储路径及文件名,默认与数据文件同目录 |
long_query_time |
慢查询阈值,单位秒,默认10秒。超过此时间的SQL会被记录 |
log_queries_not_using_indexes |
是否记录未使用索引的查询(建议开启) |
log_output |
日志输出方式,可选 FILE、TABLE 或 FILE,TABLE |
查看当前参数设置
sql
-- 查看慢查询相关配置
SHOW VARIABLES LIKE '%slow_query_log%';
-- 查看超时阈值
SHOW VARIABLES LIKE '%long_query_time%';
🔧 如何开启慢查询日志?
1. 临时开启(会话级或全局级)
sql
-- 开启慢查询日志(全局生效,重启后失效)
SET GLOBAL slow_query_log = ON;
-- 设置超时阈值为1秒(注意:需要重新连接会话才能看到变化)
SET GLOBAL long_query_time = 1;
⚠️ 注意 :
long_query_time修改后,当前会话不会立即生效,需要新建立的连接才会使用新阈值。
2. 永久生效(配置文件)
在 my.cnf 或 my.ini(Windows)中添加以下配置:
sql
[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
log_output = FILE,TABLE
保存并重启MySQL服务即可。
🧪 实操演示:产生并查看慢查询日志
Step 1:开启慢查询并设置阈值
sql
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
Step 2:执行一条较慢的查询
sql
-- 假设表 t_user 有约500万条数据,且 address 字段未索引
SELECT * FROM t_user WHERE address = '上海22';
Step 3:查看日志内容
日志默认记录在 slow_query_log_file 指定的文件中,内容示例如下:
sql
# User@Host: root[root] @ localhost [127.0.0.1] Id: 220
# Query_time: 1.552678 Lock_time: 0.003271 Rows_sent: 1 Rows_examined: 4999998
SET timestamp=1597840221;
SELECT * FROM t_user WHERE address = '上海22';
📖 慢查询日志内容解析
慢查询日志中的每一段记录包含以下关键信息:
| 字段 | 说明 |
|---|---|
| User@Host | 执行该SQL的用户名、客户端IP及连接ID |
| Query_time | 该查询执行的总耗时(单位:秒) |
| Lock_time | 等待表锁或行锁的时间 |
| Rows_sent | 最终返回给客户端的结果行数 |
| Rows_examined | 执行过程中扫描的数据行数(核心优化指标) |
| SET timestamp | SQL执行的时间戳 |
| SQL语句 | 实际执行的完整SQL |
🧠 重点分析:
-
Query_time 过长 → 需要优化SQL或索引
-
Rows_examined 远大于 Rows_sent → 说明扫描了大量无效数据,是典型的索引缺失或SQL写法不佳的信号
-
Lock_time 过高 → 可能存在锁竞争,需检查事务隔离级别或业务逻辑
📋 慢查询日志的两种输出格式
1. FILE 格式(文本文件)
可读性好,适合人工查看和分析,也支持用 mysqldumpslow 工具进行汇总统计。
sql
# 按查询时间排序,显示前10条
mysqldumpslow -s t -t 10 /path/to/slow.log
2. TABLE 格式(mysql.slow_log)
便于用SQL进行查询分析,例如:
sql
SELECT * FROM mysql.slow_log
WHERE query_time > 2
ORDER BY query_time DESC LIMIT 10;
💡 建议同时启用
FILE,TABLE,兼顾可读性和查询便利性。
🧩 常见问题与注意事项
-
开启慢查询日志对性能有影响吗?
有轻微影响,但在生产环境中开启(尤其配合合理的阈值)通常可以接受。建议在业务低峰期开启测试,再推广到生产。
-
为什么我设置了
long_query_time=1,还是记录了小于1秒的查询?检查是否开启了
log_queries_not_using_indexes,该参数会让未使用索引的查询忽略时间阈值直接记录。 -
日志文件过大怎么办?
可配置日志轮转(如
logrotate),或定期清理备份。也可通过设置expire_logs_days自动清理历史日志。
🚀 总结与优化建议
| 优化方向 | 建议 |
|---|---|
| 开启慢查询 | 生产环境务必开启,阈值建议从 1~2秒 开始 |
| 记录未使用索引的SQL | 强烈建议开启,这是发现潜在性能问题的重要途径 |
| 定期分析日志 | 使用 mysqldumpslow 或 pt-query-digest 等工具定期分析 |
| 结合执行计划 | 对慢SQL使用 EXPLAIN 分析执行计划,针对性添加索引或重写SQL |