慢查询日志
约 915 字大约 3 分钟
布欧-Lewyon
2026-05-15
首页 › MySQL › 索引与性能(在新窗口打开) › 慢查询日志
慢查询日志(Slow Query Log)记录执行时间超过阈值的 SQL 语句,是 MySQL 性能优化的第一手信息来源。打开慢日志,找到最耗时的查询,再配合 EXPLAIN 逐一优化,是标准流程。
开启慢查询日志
运行时开启
-- 查看当前状态
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
SHOW VARIABLES LIKE 'slow_query_log_file';
-- 开启慢查询日志(临时,重启后失效)
SET GLOBAL slow_query_log = ON;
-- 设置阈值:超过 1 秒记录
SET GLOBAL long_query_time = 1;
-- 设置日志文件路径
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
-- 记录未使用索引的查询
SET GLOBAL log_queries_not_using_indexes = ON;配置文件开启(持久化)
在 my.cnf 或 my.ini 的 [mysqld] 段添加:
[mysqld]
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = ON生产环境推荐
long_query_time = 1~2秒。如果设得太低(如 0.1 秒),慢日志可能被大量毫秒级查询淹没。
慢日志内容格式
# Time: 2026-05-15T10:30:00.123456Z
# User@Host: root[root] @ localhost [] Id: 12345
# Query_time: 2.345678 Lock_time: 0.000123 Rows_sent: 100 Rows_examined: 50000
SET timestamp=1747295400;
SELECT e.*, d.name
FROM employee e
LEFT JOIN department d ON e.dept_id = d.id
WHERE e.salary > 10000
ORDER BY e.create_time DESC;关键字段:
| 字段 | 含义 |
|---|---|
Query_time | 查询耗费总时间(秒) |
Lock_time | 锁等待时间(秒) |
Rows_sent | 实际返回的行数 |
Rows_examined | 扫描的行数(关键!通常远大于 Rows_sent 说明需要优化) |
分析工具
mysqldumpslow(MySQL 自带)
# 按平均时间排序,输出前 5 条
mysqldumpslow -t 5 /var/log/mysql/slow.log
# 按查询次数排序
mysqldumpslow -s c /var/log/mysql/slow.log
# 汇总结果并输出为 INSERT 友好的抽象格式
mysqldumpslow -a -g "SELECT" /var/log/mysql/slow.log输出示例:
Count: 3 Time=2.34s (7s) Lock=0.00s (0s) Rows=100.0 (300), root[root]@localhost
SELECT * FROM employee WHERE salary > N ORDER BY create_time DESCpt-query-digest(Percona Toolkit,社区推荐)
# 安装 Percona Toolkit
brew install percona-toolkit # macOS
apt install percona-toolkit # Ubuntu
# 分析慢日志
pt-query-digest /var/log/mysql/slow.log
# 从 MySQL 的 PROCESSLIST 分析
pt-query-digest --processlist h=localhost输出分为三部分:
- 总体统计:总查询数、时间分布、最慢 TOP-N
- 分组统计:按指纹(抽象后的 SQL)分组,列出各组的时间和频率
- 详细信息:每个分组的代表性 SQL 及执行计划
Performance Schema + sys schema
-- 查看耗时最长的 10 条查询
SELECT * FROM sys.statement_analysis
ORDER BY avg_latency DESC
LIMIT 10;
-- 查看全表扫描的查询
SELECT * FROM sys.statements_with_full_table_scans;
-- 查看排序导致文件排序的查询
SELECT * FROM sys.statements_with_sorting;慢查询优化流程
实际案例
案例:大表分页变慢
-- 原始 SQL
SELECT * FROM order_ ORDER BY id LIMIT 100000, 20;
-- EXPLAIN: type ALL, extra Using filesort
-- 全表扫描 + 文件排序
-- 优化:延迟关联(先查索引,再回表)
SELECT o.*
FROM order_ o
INNER JOIN (
SELECT id FROM order_
ORDER BY id
LIMIT 100000, 20
) tmp ON o.id = tmp.id
ORDER BY o.id;案例:隐式类型转换导致索引失效
-- 原始 SQL(order_no 是 VARCHAR)
SELECT * FROM order_ WHERE order_no = 123456;
-- EXPLAIN: type ALL
-- 改写
SELECT * FROM order_ WHERE order_no = '123456';
-- EXPLAIN: type ref小结
- 慢查询日志是性能优化的起点,通过
long_query_time控制阈值。 mysqldumpslow和pt-query-digest是常用的分析工具。sys.statement_analysis可从 Performance Schema 直接获取 SQL 性能排行。- 优化标准流程:慢日志 → EXPLAIN → 加索引/改写 SQL → 验证。
- 重点关注
Rows_examined远大于Rows_sent的查询。
上一节:EXPLAIN 解读 下一节:SQL 优化实战
