订单列表显示共 3,612 条,实际订单 1,204 条,翻到第 61 页开始全是空白。乍看像缓存或者权限的锅,追下去往往不是。
SELECT COUNT(DISTINCT o.id) FROM orders o LEFT JOIN order_item i ON i.order_id = o.id WHERE o.dt = '2026-03-01';
追下去是这么回事:count 查询 join 了订单明细表,一个订单三条明细就被算三次。列表查询用了 distinct 或分组,总数却没去重。两个 SQL 的 join 范围也不一致。
「join 放大总数」这类改动最怕改一半,回滚脚本先准备好,再动生产。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。日志级别临时调高可以,记得改回去,长期开着既占磁盘又掩盖真问题。
权限不要一口气开到最大,先加到够用再往上试,范围小才好收。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。
具体做法是,总数查询去掉明细表 只查主表;必须 join 时用 count(distinct order_id);列表和总数共用同一个 from 和 where 片段;拿一页数据和总数做除法 核对页数。
验收就看一点,总数显示 1,204,最后一页有数据,页数与实际条数对得上。
