跳到主内容
快讯直播
AI智模界
AI 词典

游标分页:为什么翻到后面越来越慢

一句话定义

游标分页(Cursor Pagination)是一种不靠“跳过前 N 条”、而靠“从某条记录之后接着取”的分页方式:把上一页最后一条记录的排序值当作书签(这个书签就叫游标,cursor),下一页从书签后面继续读。

偏移量分页慢在哪

最常见的分页写法是 LIMIT 10 OFFSET 20000,也就是“跳过前 20000 条,取 10 条”。问题就在“跳过”上:数据库并没有瞬移到第 20001 条的本事,它通常得沿着索引一条条数过去,把前 20000 条读出来再丢掉。每页 20 条的话,翻到第 500 页就要白数一万条(数字仅为示意)。页码越靠后越慢,而且这个慢是线性增长的。这就是很多后台列表翻到几十页之后开始转圈的原因。

打个生活化的比方

偏移量分页像排队时数人头:“从第 101 个人开始,给我 10 个人。”你必须先把前 100 个人点一遍。

游标分页像接力棒:“刚才排到张三了,从他后面那位开始,给我 10 个人。”直接找到张三,往后取十个就行,前面有多少人都不影响。

它还会漏数据

更隐蔽的问题是“位置会漂移”。偏移量描述的是一个位次,而位次会变。你在拉取一段很长的对话记录,翻到第 2 页时,会话里刚好插进来几条新消息,原来第 21 条就被挤到了第 24 条——你会重复看到它;反过来,如果前面有消息被删除或撤回,就会有一条内容从你眼皮底下滑过去,你永远拿不到它。对一次性导出、数据同步、训练语料抽取来说,这种重复和遗漏都是麻烦。

游标分页不看位次,只看锚点:WHERE (created_at, id) < (上一页最后一条的时间, id) ORDER BY created_at DESC, id DESC LIMIT 20。中途插入新数据不会影响你手里这个锚点,遍历过程是稳定的。

为什么排序键常常要写成“时间 + id”两个字段?因为时间戳可能重复,一旦并列,锚点就不唯一,可能原地打转或跳过数据。补一个唯一且递增的 id 做“决胜局”,游标才靠谱。

和相邻概念的区别

游标分页在数据库圈子里常被叫作键集分页(Keyset Pagination),两者基本是一回事,“游标”更强调把位置编码成字符串交给客户端保管。

维度偏移量分页 Offset Pagination游标分页 Cursor Pagination
翻页方式可跳到任意第 N 页只能上一页 / 下一页式推进
深翻性能越往后越慢每页成本基本恒定
数据变动时可能重复或漏记录不受前面增删影响
实现与索引简单需要稳定唯一的排序键和对应索引
典型场景后台表格、页面总数已知信息流、消息记录、批量导出与同步

实际意义

做 AI 应用时,聊天记录、Agent 运行日志、向量化任务的待处理清单,都是“持续追加、体量很大、只需要顺着往前拉”的数据。这类接口用游标分页,既能避开深翻的性能悬崖,也能保证一次全量拉取不重不漏。反过来,如果用户需要“跳到第 37 页”这种能力,游标给不了,那还是得用偏移量或者别的方案。

对普通职场人来说,一个可观察的现象是:越来越多 App 只让你“往下滑”,不给页码。这不是偷懒,而是产品在“翻得动”和“跳得准”之间做了取舍——面对会不断变化的长列表,稳定地一条条看完,往往比精确跳到某页更有用。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。