慢查询日志是定位执行效率低下的SQL语句的常用手段,它就像数据库的“记仇本”,把每一次跑得慢的查询都如实记下来,帮你直接锁定优化目标。
作为数据库运维和开发人员,你可能经常遇到这样的场景:某个页面打开要等好几秒,某个接口在高峰期频繁超时,但翻遍代码也找不到问题,这时候,慢查询日志就是最靠谱的排查起点,它不像性能监控工具那样需要额外部署,也不依赖复杂的中间件,只要开个开关,MySQL就会自动把执行时间超过阈值的SQL语句原原本本地写进日志里,我从开启方法、分析工具到优化思路,把这条链路彻底讲透。
如何开启MySQL慢查询日志?一个命令就能搞定
很多同学以为开启慢查询日志很麻烦,其实一条SET GLOBAL命令就能完成,但要注意,这种方式只对当前会话生效,服务器重启后会恢复默认值,如果想永久开启,必须修改配置文件。
慢查询日志的基本配置项
在MySQL中,与慢查询日志直接相关的参数有四个:slow_query_log(开关)、slow_query_log_file(日志路径)、long_query_time(阈值,单位秒)和log_queries_not_using_indexes(是否记录没走索引的查询),配置方式如下:
SET GLOBAL slow_query_log = ON; SET GLOBAL slow_query_log_file = '/var/log/mysql/slow-query.log'; SET GLOBAL long_query_time = 2; SET GLOBAL log_queries_not_using_indexes = ON;
如果你想永久生效,在MySQL配置文件(通常是my.cnf或my.ini)的[mysqld]段落下添加这几行,然后重启服务:
slow_query_log = ON slow_query_log_file = /var/log/mysql/slow-query.log long_query_time = 2 log_queries_not_using_indexes = ON
这里有一个容易踩坑的地方:long_query_time的默认值是10秒,也就是说,只有执行时间超过10秒的查询才会被记录,在实际业务中,10秒的阈值太宽松了,很多慢查询根本等不到10秒就影响了用户体验,行业共识认为,OLTP(在线交易处理)系统的慢查询阈值建议设置为1秒甚至更低,但具体数值要看业务场景,比如报表类查询,偶尔跑个几秒问题不大,但前台接口的SQL超过500毫秒就应该被盯上。
验证日志是否生效
配置完成后,怎么知道日志真的在写?直接查看文件内容:
tail -f /var/log/mysql/slow-query.log
然后随便执行一条耗时查询,

SELECT COUNT() FROM orders WHERE amount > 1000;
如果这条查询超过了阈值,日志里就会追加一行记录,每条记录包含查询时间、执行时长、锁等待时间、返回行数、扫描行数以及具体的SQL语句,注意,MySQL 5.7及以上版本还支持performance_schema数据库,但慢查询日志依然是更直观、开销更低的方案。
慢查询日志分析工具怎么选?从命令行到可视化
日志一旦积累起来,靠人眼一条条地看显然不现实,好在有现成的工具能把这些裸日志变成直观的数据。
命令行分析:慢查询日志怎么看?
MySQL官方自带的mysqldumpslow命令是最基础的解析工具,它能把日志中的SQL语句进行聚合,按执行次数、耗时、返回行数等维度排序,常用用法如下:
# 按平均耗时排序,查看前10条最慢的SQL mysqldumpslow -t 10 /var/log/mysql/slow-query.log # 按执行次数排序,看哪些SQL被调用得最频繁 mysqldumpslow -s c -t 10 /var/log/mysql/slow-query.log
mysqldumpslow会把相似的SQL语句归一化,比如具体的主键ID会变成N,这样聚合后的结果更有参考价值。
如果你习惯用图形界面,可以考虑Percona Toolkit中的pt-query-digest,它比官方工具更强大,能输出HTML报告,包含每个查询的响应时间占比、历史趋势等,用法也很简单:
pt-query-digest /var/log/mysql/slow-query.log > report.html
可视化工具对比
对于不习惯敲命令的同学,这里有一份常见的慢查询日志分析工具对比表格:
| 工具名称 | 类型 | 核心优势 | 适用场景 |
|---|---|---|---|
| mysqldumpslow | 命令行 | 安装即用,零依赖 | 快速查看Top N慢SQL |
| pt-query-digest | 命令行 | 报告详细,支持多维统计 | 需要深入分析报告时 |
| 简米云DAS | 云控制台 | 自动采集,图表化展示 | 使用云数据库RDS时 |
| SkyWalking | APM系统 | 链路追踪与慢SQL联动 | 微服务架构下定位问题 |
如果你的数据库部署在云上,比如酷番云或简米云的RDS,直接在控制台就能开启慢日志分析,不用自己处理文件。 云厂商一般会提供免费的日志检索功能,还能自动识别全表扫描和高频慢查询。

定位到慢SQL之后,优化思路是什么?
日志只是起点,拿到慢SQL后能不能优化掉才是关键,这里给出一个从分析到落地的标准流程。
先看执行计划
拿到一条慢SQL,第一件事不是急着加索引,而是用EXPLAIN查看它的执行计划:
EXPLAIN SELECT FROM orders WHERE customer_id = 1001 ORDER BY create_time DESC;
重点看这几列:
- type:访问类型,从好到差依次是
const、eq_ref、ref、range、index、ALL,如果看到ALL,说明全表扫描了,这是慢查询最常见的原因。 - key:实际用到的索引,如果是
NULL,说明没走索引。 - rows:预估扫描行数,这个数字越大,查询越慢。
- Extra:如果出现
Using filesort或Using temporary,说明排序或去重没有用上索引,需要额外优化。
常见优化手段
根据执行计划的结果,对症下药:
- 缺索引:给
WHERE条件中的字段加普通索引,给ORDER BY或GROUP BY涉及的字段加联合索引,注意,索引不是越多越好,要结合高频查询来设计。 - 索引失效:即使建了索引,如果SQL写法不对,也可能用不上,比如对索引字段做了函数运算(
WHERE DATE(create_time) = '2026-01-01'),或者使用LIKE '%关键词',都会让索引失效,改写为create_time >= '2026-01-01' AND create_time < '2026-01-02'就能走索引。 - 大表分页:
LIMIT 100000, 20这种写法要扫描前10万行再丢弃,性能极差,可以改成基于主键的延迟关联,或者记住上一页最后一条记录的ID,用WHERE id > 上一页最大ID来取下一页。 - 连接查询:多表
JOIN时,小表驱动大表,并且关联字段要有索引。
业内专家指出,大约80%的慢查询问题都出在索引设计或SQL写法上,真正需要改表结构的场景并不常见,所以不要一上来就动数据库表结构。
慢查询日志的常见误区与实战注意事项
在实际使用中,有几个坑经常让人栽跟头。
阈值设置多少合适
阈值太低,日志会记录大量正常查询,导致文件疯长,增加磁盘I/O和排查成本;阈值太高,又会漏掉真正的慢查询,建议先从1秒开始,观察一天后看日志大小和内容。

如果日志文件超过500MB,要么调高阈值,要么从工具层面过滤掉短时查询。 不要在业务高峰期临时调低阈值,这会让MySQL的额外开销明显上升。
日志文件过大怎么办
慢查询日志默认是追加写入的,时间一长体积会很大,处理办法有两个:
- 定期切割:用
logrotate或计划任务,每天把日志重命名并新建空文件,MySQL没有内置的日志切割功能,但重命名后执行FLUSH SLOW LOGS;即可让MySQL重新打开日志文件。 - 只保留统计结果:配合
pt-query-digest,每天生成一份聚合报告,然后清空原始日志,这样既保留了趋势数据,又避免磁盘被撑爆。
另一个常见误区是只关注执行时间,忽略了锁等待时间,慢查询日志记录的是实际执行耗时,其中包含锁等待,有时候一条SQL本身只需0.1秒,但等了2秒的锁,也会被记下来,遇到这种情况,要去查SHOW ENGINE INNODB STATUS看锁冲突,而不是盲目加索引。
Q&A:慢查询日志常见问题解析
问:开启慢查询日志会影响数据库性能吗?
答:会有一定影响,但通常很小,慢查询日志的写入是串行的,开启后每次超过阈值的查询都要多一次磁盘写操作,在写入量极大的场景下,建议使用云数据库的日志服务,或者把日志文件放到独立的磁盘分区,对于常规业务系统,性能损失可以忽略不计。
问:慢查询日志里出现大量相同SQL,但每次执行都超时,怎么处理?
答:先用EXPLAIN查看该SQL是否使用了正确的索引,排除索引失效的情况,其次查看表的数据量是否过大,是否可以通过分库分表或归档历史数据来缩小扫描范围,如果SQL本身包含复杂的子查询或OR条件,尝试拆分成多条简单SQL,最后要检查服务器CPU和内存资源,因为资源竞争也可能导致单条SQL变慢。
问:只靠慢查询日志就能保证SQL性能不退化吗?
答:不能,慢查询日志是在问题发生后记录的,只能定位已经出现的慢SQL,要想提前发现隐患,需要结合性能监控工具定期分析所有SQL的执行计划,并在代码上线前做性能测试,慢查询日志是救火工具,而优化意识和良好的开发规范才是防火墙。