postgresql - 为什么使用 PSQL 进行偏移分页有意义?
问题描述
我一直在研究使用 PSQL dbms 进行分页(按时间戳分页)。我目前的方法是建立一个 b+ 索引来大大降低寻找下一个块开始的成本。但是我在教程和 NPM 模块(如 express-paginate (https://www.npmjs.com/package/express-paginate))中看到的任何地方,人们似乎都使用一种或另一种方式的偏移量来获取块,或者无论如何都获取所有数据但只是将它们分块发送,这对我来说似乎并不是分页的完整优化。
我可以看到他们仍在通过延迟加载和流式传输块进行优化(从而节省带宽和客户端上的任何下载/处理时间),但是由于 psql 上的偏移量仍然需要扫描前一行。在用户想要查看所有数据的最坏情况下,这种方法是否具有非常高的服务器成本,因为如果您有 n 个块,您将访问第一个块 n 次,第二个块 n-1次,第三块 n-2 次,等等。我知道这实际上是在 IO 方面,所以它不是那么贵,但它仍然困扰着我?
我在这里遗漏了一些非常明显的东西吗?我觉得我是因为似乎有更多成熟和经验丰富的工程师似乎正在使用这种方法。我猜我的理解中缺少方程式或机制的某些部分。
解决方案
不,你很明白这一点。
这么多的人和工具仍然提倡使用OFFSET
and LIMIT
(或者FETCH FIRST n ROWS ONLY
,使用标准的语言)进行分页的原因是他们对数据库知之甚少。这很容易理解LIMIT
,OFFSET
即使你对你来说“索引”这个词除了“一本书的最后几页”之外没有其他含义。
还有另一个原因:要实现键集分页,您ORDER BY
的查询中必须有一个子句,该ORDER BY
子句必须包含唯一列,并且您必须创建一个支持该排序的索引。
此外,您的数据库必须能够处理诸如
... WHERE (name, id) > ('last_found', 42)
并支持对它们进行多列索引扫描。
由于许多工具都力求支持多个数据库系统,因此它们可能会采用简单但低效的方法,该方法适用于大多数数据库系统上的每个查询。
推荐阅读
- c++ - clang-tidy check to remove unnecessary class name before member function
- audio - Mapping text to Mel Spectrogram and conversion of text to input feature representation in Tacotron 2
- python - pip install pyautogui says the same thing over and over again
- java - How to get all classes used in decorator design pattern?
- graphql - Updated react apollo cached but ui didnt update
- angular - 在生成的 HTML 中监听点击事件
- docker - 无法从 GCP Container Registry 拉取镜像
- reactjs - 结果页面中的搜索表单 - ReactJs
- ms-word - 表内的内容不生成 TOC
- javascript - 如何处理来自python的多个返回作为JavaScript中的多个参数?