我们需要工具支持键集分页 (use-the-index-luke.com)
您是否知道分页非常麻烦但很容易避免?offset
offset
指示数据库跳过查询的前 N 个结果。但是,数据库仍必须从磁盘获取这些行并按顺序排列它们,然后才能发送以下行。
这不是实现问题,而是设计的方式:offset
...行首先根据<顺序依据子句>进行排序,然后通过从一开始就删除<结果偏移子句>中指定的行数来限制......
SQL:2016, 第 2 部分, §4.15.3 派生表
这里的关键点是它只需要一个参数:要删除的行数。没有更多的上下文。数据库对此数字唯一可以做的就是获取和删除这么多行。换句话说,在数据库上投入了大量的工作——无论是SQL还是NoSQ L。offset
offsets
但问题并不止于此:想想如果在获取两个页面之间插入新行会发生什么?offset
1仅提取前 10 行选定的行第 1 行 第 2 行 第 3 行 第 4 行 第 5 行 第 6 行7 行 8 行 9 行 10 行 11 行 12 行 13行142插入新建行3删除的行选择偏移 10 仅获取接下来的 10 行新建行
使用 ➌ 跳过以前提取的条目❶ 时,如果获取两个页面之间插入了新行,您将获得重复项➋。还有其他可能的异常,这只是最常见的异常。offset
这甚至不是数据库问题,而是框架实现分页的方式:它们只是说要获取哪个页码或要跳过多少行。仅凭这些信息,任何数据库都无法做得更好。
另请注意,偏移问题可能有不同的语法:
-
偏移关键字
-
2参数限制
[偏移量,]
限制(1参数限制
很好) -
基于行编号的下限过滤(例如
row_number()
,rownum
,...)。
所有这些方法的根本问题是,它们只提供了要删除的行数,而不再提供上下文。在本文中,我指的是这些方法中的任何一种。offset
无偏移寿命
现在想象一个没有这些问题的世界。事实证明,没有它的生活非常简单:只需使用仅选择您尚未看到的数据的子句。offset
where
为此,我们利用了我们在有序集合上工作的事实——你确实有 anclause,不是吗?一旦有了明确的排序顺序,我们就可以使用一个简单的过滤器来只选择我们最后看到的条目后面的内容:order by
SELECT ...
FROM ...
WHERE ...
AND id < ?last_seen_id
ORDER BY id DESC
FETCH FIRST 10 ROWS ONLY
这是基本配方。在多列上排序时会变得更有趣,但想法是相同的。该配方也适用于许多NoSQ L系统。
这种方法(称为查找方法或键集分页)解决了如上所述的漂移结果问题,甚至比这种方法更快。如果你想知道使用or键集分页时数据库内部发生了什么,看看这些幻灯片(基准,基准!):offset
offset
在第43 张幻灯片上,您还可以看到键集分页有一些限制:最明显的是您无法直接导航到任意页面。但是,使用无限滚动时这不是问题。无论如何,显示要单击的页码是一个糟糕的导航界面——恕我直言。
如果您想阅读有关如何在SQL中正确实现键集分页的更多信息,请阅读本文。即使您不参与 SQL,在开始实现任何内容之前也值得阅读该文章。
但是框架...
首选键集分页的主要原因是缺乏工具支持。大多数工具提供基于键集分页的分页,但没有提供任何使用键集分页的便捷方法。offset
offset
请注意,键集分页会影响整个技术堆栈,直到在浏览器中运行的JavaScript执行AJAX无限滚动:而不是将简单的页码传递给服务器,您必须将完整的键集(通常是多列)向下传递给服务器。
支持键集分页的框架名人堂正在不断增长:
JavaScript
-
节点.js:书架-光标-分页
-
海量.js:密钥集文档
蟒
-
Django REST 框架:游标分页
-
姜戈无限滚动分页
-
姜戈分块器
-
SQL Alchemy sqlakeyset.
Java / JVM
-
jOOQ — Java 面向对象的查询
-
炽热持久性
-
斯卡拉部分结果
.PHP
-
拉拉维尔 8.0+: 光标分页器
。网
-
DRF 类似分页
-
先生。EntityFrameworkCore.KeysetPagination
红宝石
-
续集::寻页
-
下一页
-
order_query
佩尔
-
DBIx::Class::Wrapper
这就是我需要你帮助的地方。如果你正在维护一个以某种方式涉及分页的框架,我请求你,我敦促你,我恳求你,也为键集分页构建本机支持。如果您对细节有任何疑问,我很乐意为您提供帮助(论坛,联系表格,推特)!
即使您只是使用应该支持密钥集分页的软件,例如内容管理系统或网上商店,也要让维护人员知道它。您可以只提交功能请求(链接到此页面),或者,如果可能,提供补丁。同样,我很乐意帮助正确处理细节。
以WordPress为例。
传播信息
键集分页的问题不是技术问题。问题只是它在现场几乎不为人知,也没有工具支持。如果您喜欢少分页的想法,请帮助传播这个词。推特它,分享它,邮寄它,你甚至可以重新写这篇文章(CC-BY-NC-ND)。也欢迎翻译,请事先与我联系 - 我也会在此页面上包含翻译的链接!offset
哦,如果你在写博客,你也可以在你的博客上添加一个横幅,让你的读者知道它。我准备了一个带有一些常见横幅格式的NoOffset 横幅库。只需选择最适合您的。
如果你喜欢我解释事物的方式,你会喜欢我的书。
相关
-
无偏移横幅图库
-
文章:获取下一页 — 偏移量与键集分页