列表接口 total 返回 1200,每页 20 条,用户点到第 50 页直接空白,实际数据只有 830 条。乍看像缓存或者权限的锅,追下去往往不是。
SELECT count(*) FROM orders WHERE status = 'paid' AND created_at >= '2026-03-01';
追下去是这么回事:total 用的是缓存里的旧值或者另一张统计表的估算值,跟当前查询条件不是同一套。筛选条件变了 total 没跟着变,前端按 total 算出来的页数就偏多,末尾几页全是空的。
「分页 total」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。测试环境和线上的差别,往往就在版本号和那几行被忽略的配置上。
线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
具体做法是,total 用和列表同一条 where 条件的 count 查询 别复用缓存值;count 太慢就单独缓存 但缓存键要带上全部筛选参数;前端遇到空页回退一页 不要只依赖 total 算页数;把筛选后的总数和实际翻页结果做一次对账。
验收就看一点,加筛选条件后 total 和实际能翻到的最后一页对得上 第 50 页不再出现空白。
