生产统计全为 0:用数据库聚合替代全量明细加载
一次生产订单统计全部显示为 0 的排查:数据实际存在,但全量明细汇总在生产规模下超时,页面保留了初始值。
一个订单状态页面在测试环境正常,生产环境的入库、出库和各节点数量却全部显示为 0。页面列表能看到大量订单,数据库也确认近期业务数据存在,因此“0”不是事实,而是汇总请求没有及时成功返回。
根因不是索引差异
旧接口为了统计数量,分别发起多次超大分页查询,把明细加载到 Java 后再分组。每次分页还会额外执行 count SQL。一次页面刷新最终串行触发多条重查询。
测试库数据量很小,这种实现仍能在很短时间内返回;生产流转记录规模大几个数量级,同样的查询需要十几到二十多秒,多项统计串行后超过页面等待时间。前端没有明确失败态,于是保留初始化的 0,看起来就像生产没有订单。
两套环境的核心索引与统计信息没有足以解释差异的异常。真正的问题是算法复杂度随着生产数据增长失控。
将计算推回数据库
修复为入库和出库分别增加专用聚合 SQL:
- 先按公司、仓库、订单时间和页面条件筛选目标订单;
- 只处理这些订单相关的流转记录与明细;
- 在数据库内一次计算唯一订单总数和各节点数量;
- 返回单行聚合结果,不再经过分页框架的额外 count;
- 无数据时所有字段明确返回数值 0。
接口地址、请求参数和响应字段保持不变,因此前端和其他调用方不需要迁移。
前端也做了两项调整:翻页不再重复请求汇总;汇总失败时显示占位符和明确提示,不再把错误伪装成真实的零。
只读对账与结论
验证在相同时间窗口和同一只读快照内比较新旧 SQL。旧查询单项约需二十多秒,新聚合通常在一秒内返回,唯一订单总数和各节点数量完全一致。
边界用例还覆盖:
- 精确单号查询;
- 高级筛选;
- 没有数据的未来时间窗口;
- 存在订单但没有流转记录;
- 测试环境原有小数据集。
所有验证都只执行 SELECT,没有直接修改生产数据或部署应用。
这次问题的教训是:页面上的 0 可能是默认值,也可能是失败值。统计接口应该直接返回聚合结果,前端也必须区分“真实为零”和“请求失败”。在生产规模下,能在测试库跑通的全量加载方案并不等于可用。
先说明系统,再说明症状
如果需要生产排障、DevOps 交付或物流系统集成协作,请提供当前表现、预期结果、受影响环境、可用日志或数据样例,以及发布限制。我会从现有证据开始判断。
通过邮件开始