数据库慢查询的分层排查:从慢日志到执行计划的一次复盘

举报
yd_252559278 发表于 2026/11/03 09:55:38 2026/11/03
【摘要】 引言上周一次接口超时报警,把我们带回一个老问题:数据库变慢了。日志里只有超时,监控只显示连接数上涨,真正原因藏在几层之下。这次复盘不讲单一技巧,而是讲分层排查:先确认慢在哪一层,再收敛范围,最后才改动。第一层:区分数据库慢,还是应用在等接口耗时高,不等于数据库执行慢。先对比三组时间:应用端总耗时、数据库侧执行耗时、排队等待连接的时间。总耗时远大于执行耗时,问题可能在连接池、网络或线程等待;执...

引言

上周一次接口超时报警,把我们带回一个老问题:数据库变慢了。日志里只有超时,监控只显示连接数上涨,真正原因藏在几层之下。这次复盘不讲单一技巧,而是讲分层排查:先确认慢在哪一层,再收敛范围,最后才改动。

第一层:区分数据库慢,还是应用在等

接口耗时高,不等于数据库执行慢。先对比三组时间:应用端总耗时、数据库侧执行耗时、排队等待连接的时间。总耗时远大于执行耗时,问题可能在连接池、网络或线程等待;执行耗时本身高,再往数据库内部查。这次属于后者,慢日志里同一查询反复出现,平均耗时从几十毫秒涨到两秒以上。

第二层:用慢日志排序,而不是凭感觉猜

慢日志的价值在于可以排序。按出现次数乘以平均耗时排序,优先处理总耗时占比最高的那几条,而不是单次最慢的那一条。单次最慢可能是冷缓存或偶发大结果集,高频慢才是稳定成本。我们把目标查询抽出来,在只读环境单独重放,确认它在没有业务流量时仍然慢,先排除锁等待和突发流量的干扰。

第三层:看执行计划,别只看 SQL 文本

SQL 写得短,不代表执行得快。执行计划重点看四点:是否走了预期索引,扫描行数与返回行数的差距,是否出现临时表或文件排序,连接顺序是否合理。这次查询走了索引,但扫描行数是返回行数的几十倍,原因是范围条件放在索引列之后,索引只能用到前半部分。把等值条件前置并重新评估范围条件后,扫描量明显下降。索引存在却未被选中时,也要先确认统计信息是否过期,再看选择性是否真的支持这条索引。

第四层:看锁与并发,别只看单条查询

单条查询空闲时很快、高峰期很慢,往往与锁和并发有关。长事务持有锁,会阻塞后面的更新;更新又会阻塞读,读超时反过来拖住连接池。排查时要同时看运行中的事务、等待事件和锁等待链。我们的做法是缩短事务边界,把只读查询移出写事务,把大批量更新拆成小批次。一次提交几万行看似省事,实际上锁持有时间长、回滚代价大,拆小后整体反而更稳。

第五层:看数据增长与返回量

查询合理、索引合理,但数据量一直在涨,慢就是迟早的事。要看表数据量、索引大小、分区情况,以及查询是否真的需要返回那么多列。只取需要的列、限制返回行数、按时间分区裁剪,都是不改业务语义的降扫描方法。我们最后把历史数据按月归档,热表只保留近期数据,查询默认带时间范围,避免全表扫描旧数据。

检查清单与结语

复盘后形成一张清单:确认耗时发生在应用、连接还是执行;用慢日志按总耗时排序;看执行计划的扫描量与排序;检查长事务与锁等待链;评估数据增长与返回量。每一步留证据,包括执行计划前后对比和改动前后的耗时分布。慢查询排查不是一次用上所有手段,而是按层收敛,改动越小、证据越清楚,线上风险就越低。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。