两个"慢":大表查询和定时轮询

这篇记两次"慢"的排查。一个是查询慢,一个是处理延迟大,表面看是两回事,其实都是没想清楚数据是怎么被取出来的。先说好,两个都还没有改完,文里的结论我会区分哪些是实测、哪些是推测。

取个最新时间要几十秒

有个按时间展示的页面特别慢:取全站最新时次的查询大约 34 秒,时次列表约 22 秒,第一次打开加起来快一分钟。

能确定的事实是:这张表大概 5 千万行,主键顺序是站号、时间、项目号,没有以时间开头的索引。所以按时间取最大值、按时间过滤,很可能就是因此慢的。但这次没拿到执行计划,所以我只能说"很可能",不能写成"已经证明是全表扫描"。

接下来打算这么做:先拿真实的执行计划和基线耗时,再评估建一个时间开头的索引(这个需要库的负责人批准),短时缓存和合并重复请求当补充。有一点要守住:不能为了快就偷偷缩小站点范围或时间窗口,那会改变查询的含义,页面上看到的数据就不是原来那份了。另外,没实测之前,我不会承诺能快多少。

定时扫窗口,不等于来一个处理一个

另一个是个需求:"文件来一个就处理一个",测试要量的是原始文件落地到产品文件生成之间的时间差。

我读了现在的服务代码:它是定时触发,把最近一段时间窗口里的所有文件当成一批,只要窗口里有文件,就启动一次脚本把整个窗口过一遍,靠恢复开关跳过已经生成的。所以它其实是定时轮询一个时间窗口,不是新文件到了就处理那一个,量出来的时间差会被轮询间隔拉长,还可能因为每次都把窗口整个过一遍而更慢。

这一条我只是读了代码、给出了改造方案,因为是改已有逻辑,需要先确认,所以没有"改好了"这回事。方案的思路是:缩短扫描间隔,只列目录、不启动脚本;记住已经处理过的文件名,只挑新文件去处理。

小结

两次慢的原因,一个在"怎么找数据",一个在"什么时候去找"。碰到慢,我现在先问两件事:

  1. 这次查询或处理,实际扫了多少数据?有没有执行计划或日志能证明,而不是凭感觉。
  2. 触发方式是"事件来了才做",还是"到点了统一扫一遍"?量出来的延迟里有多少是等出来的。

posted on 2026-11-02 10:20  因n而在  阅读(4)  评论(0)    收藏  举报

导航