首页/数据/NoSQL 速查/分页策略对照:offset 与游标
选型与架构50 条

分页策略对照:offset 与游标

深分页的共同问题是 offset 越大代价越高:SQL OFFSET 要逐行跳过,MongoDB skip 类似,ES 的 from+size 受 index.max_result_window 限制。键集/游标分页用上一页末位值作为下一页条件,代价与页深基本无关,代价是不能随机跳页。

NoSQL 速查数据更新于 2026-10-12

方式对照

方式示例适用
offsetLIMIT 20 OFFSET 100000;MongoDB skip(100000)小偏移、需要页码跳转
键集WHERE (ts, id) < (上一页末值) ORDER BY ts DESC, id DESC LIMIT 20顺序翻页、导出
游标MongoDB _id 游标;ES search_after + PIT深分页、滚动列表

键集分页(SQL)

键集分页(SQL)
-- 第一页
SELECT id, ts, msg FROM events ORDER BY ts DESC, id DESC LIMIT 20;

-- 下一页:用上一页最后一条的 (ts, id) 作为起点
SELECT id, ts, msg FROM events
WHERE (ts, id) < ('2026-10-12 00:00:00', 1001)
ORDER BY ts DESC, id DESC LIMIT 20;
排序键组合必须能确定唯一顺序:时间戳加 _id 之类的唯一列兜底,否则边界处会漏行或重复行。

易错点

  • 用 offset 做后台全量导出:页数越多每页越慢,中途数据变化还会错行,导出用游标加快照
  • 游标翻页要求排序键唯一且稳定,随机会话中用随机排序无法使用该模式

数据来源与参考

  • Elasticsearch Guide: Paginate search results
  • MongoDB Manual: cursor.skip()
  • PostgreSQL Docs: SELECT 中的 LIMIT 与 OFFSET
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌