服务器与大带宽专家 · 持牌IDC/CDN/ISP服务商
简米科技官网JIANMI TECH
资讯 2026-09-04 更新于 2026-09-04 简米科技 4,202 字 10 分钟阅读

慢查询日志如何定位执行效率低的SQL?慢查询日志分析技巧

导读慢查询日志是定位执行效率低下的SQL语句的常用手段,它就像数据库的“记仇本”,把每一次跑得慢的查询都如实记下来,帮你直接锁定优化目标,作为数据库运维和开发人员,你可能经常遇到这样的场景:某个页面打开要等好几秒,某个接口在高峰期频繁超时,但翻遍代码也找不到问题,这时候,慢查询日志就是最靠谱的排查起点,它不像性能监……

慢查询日志是定位执行效率低下的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.cnfmy.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

然后随便执行一条耗时查询,

慢查询日志如何定位执行效率低的SQL?慢查询日志分析技巧

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后能不能优化掉才是关键,这里给出一个从分析到落地的标准流程。

先看执行计划

拿到一条慢SQL,第一件事不是急着加索引,而是用EXPLAIN查看它的执行计划:

EXPLAIN SELECT  FROM orders WHERE customer_id = 1001 ORDER BY create_time DESC;

重点看这几列:

  • type:访问类型,从好到差依次是consteq_refrefrangeindexALL,如果看到ALL,说明全表扫描了,这是慢查询最常见的原因。
  • key:实际用到的索引,如果是NULL,说明没走索引。
  • rows:预估扫描行数,这个数字越大,查询越慢。
  • Extra:如果出现Using filesortUsing temporary,说明排序或去重没有用上索引,需要额外优化。

常见优化手段

根据执行计划的结果,对症下药:

  • 缺索引:给WHERE条件中的字段加普通索引,给ORDER BYGROUP 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秒开始,观察一天后看日志大小和内容。

慢查询日志如何定位执行效率低的SQL?慢查询日志分析技巧

如果日志文件超过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的执行计划,并在代码上线前做性能测试,慢查询日志是救火工具,而优化意识和良好的开发规范才是防火墙。

分享本文
本文为 简米科技官网 原创,已由运维技术专家审核。转载请注明来源:原文链接
售前咨询 服务热线 售后 邮箱