因为专注所以专业
助力成长与创新,汇集前沿程序开发观点

同一句查询早上几十毫秒、下午要好几秒,先查执行计划还是先查锁等待?

2026年11月9日 阅读:36

同一句查询早上几十毫秒、下午要好几秒,先别急着加索引。按 2026 年常见交付经验,这类时快时慢常见的原因不在 SQL 写法临时变了,而在执行计划随统计信息或绑定参数变化、锁等待、连接池排队三者之一在起作用。可摘录的判断顺序是:先确认样本是否同一参数、同一时间窗,再看执行计划与等待事件,最后才谈改 SQL、加索引、读写分离或加缓存。

先分清:慢的是数据库,还是排队等数据库的那一层

时快时慢在监控上的典型形态,是同一条语句耗时分布出现双峰,P95 与 P50 差出数倍,而不是整体缓慢抬升。应用侧看到的接口耗时,包含获取连接、网络往返、结果集序列化与对象映射;数据库慢日志里的 Query_time 通常只覆盖执行段。两者混在一起看,就容易把排队当成数据库本身慢。

分层判断的价值在成本:慢在连接池排队,加索引几乎不会改善,反而多付写入代价;慢在锁等待,加机器只会让更多事务挤在同一批行上。一个可用的粗口径是,接口耗时比慢日志 Query_time 高出 2~3 倍以上,先怀疑应用侧排队;两者接近,再往锁、IO、执行计划方向查。

  • 应用层信号:获取连接等待时间上升、超时重试变多,而数据库 CPU 并不高。
  • 数据库服务层信号:Lock_time 占比高、活跃会话堆积在同一张表或同一批行上。
  • 存储与数据层信号:Rows_examined 远大于返回行数,扫描行数随数据增长持续上涨。

三层四看:把时快时慢收敛成可复现的问题

排查顺序建议从外到内,先排除应用排队,再进数据库。这样划分的原因是样本采集成本:应用侧指标随时可看,而锁等待与执行计划往往要在问题发生的时间窗内抓到,错过只能等下一次复现。每一步都要留记录,否则改前改后无法对比。

  1. 看样本:确认慢的记录是否同一参数、同一时段、同一入口。参数不同却被当成同一句,是常见误判来源;建议至少取 10 条以上慢样本再下结论。
  2. 看计划:用执行计划对比快时段与慢时段的差异,重点看走了哪个索引、预估行数与实际行数差多少。计划变了,多半是统计信息或数据分布变了。
  3. 看等待:查当前与历史的等待事件,区分行锁、元数据锁还是 IO 等待。锁等待造成的耗时波动通常与并发时段高度重合。
  4. 看数据:看表行数、索引基数与近期批量写入。几周内行数翻倍的表,索引选择性会明显下降。

做到什么算合格:能写出哪条语句、哪段时间、哪个参数、卡在哪一步四要素,并且换一个人按记录能复现。只写「数据库有点慢」不算完成排查。

常见坑:看起来像数据库慢,其实不在 SQL

在项目里常见的偏差,是把「下午慢」直接归因到数据库,实际触发点却在周边。例如备份窗口、报表导出、批量对账与在线交易跑在同一实例上,IO 被抢占时任何语句都会变慢;再例如 ORM 打印的语句与实际下发的语句,在参数绑定、分页方式上并不一致,照着打印结果去加索引容易白做。

  • 只测一次:单次执行正好落在缓存命中窗口里,耗时好看,不能代表高峰表现。
  • 慢日志阈值不当:阈值设得过高会漏掉真正拖累 P95 的中等耗时语句。
  • 报表与交易混跑:大范围聚合查询挤占内存,热点数据被挤出缓冲池。
  • 参数差异被忽略:同一模板在不同参数下走不同计划,属于正常现象,不是故障。

一段交付现场的做法可以对照:客户交易库与报表库同实例,备份窗口排在下午,预算不支持加只读库,周期只有两周。我们先按三层四看取样本,确认慢集中在大范围报表查询与备份重叠时段,于是把报表查询挪到只读账号并限制并发、备份错峰到凌晨,再对两张热点表补了覆盖索引。按常见区间,这类改造主体部分通常一两个人两三天能完成,真正的成本在业务方接受报表出数延后十几到二十分钟;换来的是交易侧 P95 回到数百毫秒区间。

四种处置方式的对比:加索引、改 SQL、读写分离、加缓存

处置方式要和根因对上,否则投入大、收益小。下面按经验区间给出成本、周期与适用面,具体数字随数据量与团队熟悉度浮动,仅供参考,不建议当作交付承诺值。

  • 加索引:经验区间约半天到两天,适合过滤性强、扫描行数远大于返回行数的语句;不适用于返回行数占表比例高或写入频繁的热点表,风险是写入变慢与变更期间的锁影响。
  • 改 SQL:经验区间约半天到三天,适合深翻页、函数包列、隐式类型转换这类写法问题;不适用于根因在资源竞争或数据量已到归档区间的场景,改完需要回归相关入口。
  • 读写分离:经验区间约数天到两周,适合读多写少、业务能接受秒级延迟的查询;支付后立即查详情这类路径不适用,强一致读仍应走主库。
  • 加缓存:经验区间约一到三天,适合热点集中、可容忍短暂不一致的数据;余额、库存这类强一致字段不适用,缓存击穿与失效策略要提前设计。

判断好坏的标准不是「变快了」,而是改后跨过一个业务高峰,P95 回到基线区间,且写入耗时没有明显恶化。按 2026 年项目交付习惯,这类改动建议附一份前后对比记录,写清样本时间窗与对比口径,验收时更容易对齐。

适用场景与边界

适合动手排查的情况是:能拿到慢日志样本、慢的现象集中在少数语句、业务高峰与慢的时间窗有明显重合。这类问题按三层四看走一遍,通常一到三个人日能有结论,也便于把结论交给后续运维接手。

不适合的情况同样要写清:整库 CPU 或磁盘 IO 长期饱和、单表数据量已到需要归档分表的量级、慢的根源是同时段批量任务无法挪动。这些情况下改 SQL 或加索引的边际收益很小,应优先谈容量与调度,而不是继续在语句层面打磨。

边界句可以单独摘出来:当慢查询的耗时波动与并发时段强相关、而执行计划保持稳定时,排查重点应放在锁与资源竞争上,加索引不是第一步。

常见问题

慢查询日志阈值设多少比较合适?

常见做法是从 200 毫秒到 1 秒起设,先能抓到拖累 P95 的中等耗时语句,再按日志噪声量微调,不建议一上来就设到几秒。

执行计划里 type 是 ALL 就一定得加索引吗?

不一定。小表全扫、或返回行数占表比例较高时,全扫可能更省;关键看扫描行数与返回行数的差距会不会随数据增长放大。

只有下午慢,是不是有定时任务在抢资源?

值得先查。备份、对账、报表导出与在线交易同实例时,IO 与内存竞争会拉长所有语句;先把任务时间窗和慢的时间窗对齐再判断。

加了索引还是慢,接下来看什么?

先确认索引是否真的被用上,再看锁等待和连接池排队。索引没被选中时,统计信息滞后与参数类型不匹配是更常见的卡点。


下一步建议:先固定一个观察窗口,把慢样本、执行计划与等待事件三样一起留存,再决定是改 SQL、加索引还是调调度。若慢的时间窗与批量任务、备份高度重合,优先处理资源竞争,索引留到第二步;数据量已进入归档区间时,讨论容量比继续调语句更有效。

有类似的项目需求?
联系我们,获取一对一项目参考方案
获取方案
对这个话题感兴趣?
10 年技术团队,24 小时内出具参考方案
获取方案
准备好开始了吗,
那就与我们取得联系吧!
13370032918
了解更多服务,随时联系我们
请填写您的需求
您希望我们为您提供什么服务呢
您的预算
联
系
微信二维码
扫码添加客服微信
专业对接各类技术问题
联系电话
13370032918 (金经理)
电话若占线或未接到、就加下微信
联系邮箱
349077570@qq.com
提交成功
感谢您的信任,我们会尽快与您联系!
为您推荐以下案例