SQL只耗0.2毫秒,慢在跨区往返
Agent Commons 的延迟排查显示,查询执行仅需约0.2毫秒,Worker 与数据库之间的网络往返及冷启动才是主要耗时。团队通过健康端点分别暴露运行区域、SQL耗时、往返耗时和初始化耗时,并撤回了导致延迟上升的改动。
AI 深度解读
Agent Commons 的一次读取,SQL 只执行了 0.2 ms,请求却可能等上几秒。作者追查后发现,主要开销藏在启动检查里:Worker 要连续往返数据库六次,业务查询还没开始,美国节点就先花了约 1.1 s。
这次排查值得看的是定位方法:先尝试调整部署位置,发现前后对比不足以说明问题,再把一次调用拆开计时,找到串行等待。对于使用远程数据库的服务,这比盯着慢 SQL 更有参考价值。
SQL 很快,请求为什么还会慢?
2026-10-22,Agent Commons 的调用耗时在 0.4 到 5 s 之间,还有一次读取在 20 s 后超时。同一天,agent 客户端报告过 /mcp 首次回答为空,已在 #182 修复,因此作者继续排查首次调用的延迟。
数据库使用 Cloudflare D1,位于新加坡附近。作者所在位置的检查请求会进入美国的 SJC、LAX 节点,每次查询都要跨太平洋往返。
他们先启用 Cloudflare smart placement,让 Worker 靠近后端运行,变更编号为 #184。前后各取 10 个样本,观察结果更慢,于是在五分钟内通过 #185 回退。
但作者承认,这个实验无法证明调整位置有害。此前一小时,即使什么都不改,相同接口的延迟也会按分钟波动 2-3 倍。各测 10 次,可能只是碰上了不同的网络状态。
总耗时变了,不等于刚做的改动造成了变化。
把一次调用拆开,才能找到六次等待
作者在 #186 增加了公开诊断接口,分别记录 Worker、数据库执行和启动检查的耗时:
GET https://commons.dooza.ai/api/health
{"ok":true,"colo":"SIN","schemaMs":20,
"ping":{"wallMs":11,"sqlMs":0.2},
"latest":{"wallMs":7,"sqlMs":0.2},"totalMs":38}
这里最该对照的是 wallMs 和 sqlMs。后者是 D1 报告的查询执行时间,前者是 Worker 发起数据库调用到收到结果的时间。两者之差,按作者的划分就是往返开销。
其余字段也各有用途:
colo表示 Worker 实际运行的节点。schemaMs表示启动时检查表结构的耗时,隔离实例已经预热时为 0。totalMs表示服务内部记录的总耗时;调用方总耗时减去它,可以估算调用方与节点之间的网络开销。
接口只读取最新条目的 id,返回计时信息。
拆开以后,问题很清楚:冷启动依次执行 schema batch、种子数据清理、第一张表的列检查、补列、第二张表的检查,以及 notifications 表相关操作。六个步骤前后等待,SQL 再快也要付六次往返成本。
服务流量少,又分散在多个节点,多数请求会落到冷的隔离实例。美国调用者通常要先等约 1.1 s,才轮到自己的业务查询。
作者随后将启动工作合并,把两处列检查并行执行,只在确实缺列时修改表结构。原文这里缺了一段完整的改动说明,没有提供可复现代码;能够确认的是,部署后从 SJC、MAD、CDG 测得 schemaMs 为 168-181 ms,作者称启动路径降到一次往返。
一次往返若要 180 ms,连续六次快速查询也足以吃掉一秒左右。
我的判断
这次排查最有价值的地方,是把「数据库慢」拆成了「执行慢」和「等结果慢」。对于跨区域访问数据库的 Worker,检查串行 await、循环查询和层层启动检查,确实应该排在优化 SQL 之前。
但适用前提要分清。作者服务的数据库离美国节点较远,流量又不足以让各地实例持续预热;一般团队是否也经常冷启动,需要自己测。原文没有给出冷启动占比,也没有报告改动后的完整延迟分布,168-181 ms 只能说明当时几个节点的启动检查结果。
smart placement 的结论也应保留。第一次实验受波动干扰,不能据此认定计算靠近数据无效。位置调整与减少串行调用可以同时做,分别解决单次往返距离和往返次数的问题。
把迁移放进请求启动路径还会增加重复检查成本。若部署流程允许,独立执行迁移也是替代方案,但原文没有比较两种做法的维护成本或可靠性,不能替作者补上结论。
能拿来做什么
- 排查 Node 或 Worker 接口时,同时记录数据库调用的总耗时与数据库报告的执行耗时,先确认时间花在哪里,再决定是否改 SQL。
- 检查 AI 生成代码里的串行
await。对没有依赖关系的远程检查,评估并行或批处理,别只看单条查询够不够快。 - 遇到延迟按分钟明显波动时,先补调用内部计时。前后各取少量样本,很难判断一次配置调整是否有效。
- 将冷启动与预热后的请求分开观察。原文的
/api/home在预热后仍串行执行约六次查询,美国节点耗时约 1 s;启动优化完成后,业务路径仍需单独排查。