在PostgreSQL中使用“游标”进行分页[duplicate]

这个问题在这里已经有答案了

9年前关闭的

可能重复:
如何为API客户端提供1000000个数据库结果

了解游标的使用是使用PostgreSQL实现“分页”的好方法

用例是我们希望向我们的API客户机提供超过100000行。我们认为实现这一点的一个好方法是允许客户机批量(页面)请求信息。客户端一次可以请求100行。我们将返回100行以及一个游标,然后当客户机准备就绪时,他们可以使用我们发送给他们的游标请求接下来的100行

但是,我对游标的工作原理以及游标的具体使用方式和时间有点模糊:

  • 游标是否要求数据库连接保持打开状态
  • 游标是否在事务内部运行,锁定资源直到“关闭”
  • 还有其他我不知道的“陷阱”吗
  • 有没有其他更好的方法来处理这种情况

非常感谢

在处理大型数据集的小型intranet应用程序中,游标是分页的合理选择,但您需要准备在超时后丢弃它们。用户喜欢闲逛、吃午饭、休假两周等等,然后让应用程序继续运行。如果它是一个基于网络的应用程序,那么甚至还有一个问题,那就是“运行”是什么,以及如何判断用户是否还在

它们不适用于具有高客户端数量的大型应用程序以及随机出现的客户端,如基于web的应用程序或web API。我不建议在你的应用程序中使用游标,除非你有一个相当小的客户端数量和非常高的请求率。。。在这种情况下,发送小批量的行将非常低效,您应该考虑允许范围请求等

游标有几个代价。如果光标未处于按住状态,则必须使交易保持打开状态。打开的事务可能会阻止autovacuum正常工作,从而导致表膨胀和其他问题。如果使用HOLD声明游标,并且事务未保持打开状态,则您必须支付实现和存储可能较大的结果集的成本-至少,我认为HOLD游标就是这样工作的。另一种方法也同样糟糕,在游标被销毁之前保持事务隐式打开,并防止清除行

此外,如果使用游标,则无法将连接返回到连接池。每个客户端需要一个连接。这意味着只需维护会话状态就可以使用更多的后端资源,并对基于游标的方法可以处理的客户端数量设置了一个非常实际的上限

与具有限制和偏移量的无状态连接池方法相比,管理有状态的、基于光标的设置还存在复杂性和开销。您需要让您的应用程序在超时后使游标过期,否则您将面临服务器上潜在的无限资源使用,并且您需要跟踪哪些连接有哪些游标,哪些用户有哪些结果集

一般来说,尽管它可能非常低效,LIMITOFFSET可能是更好的解决方案。不过,搜索主键通常比使用OFFSET更好

顺便说一下,您正在查看PL/pgSQL中游标的文档。您需要此作业的常规SQL级别游标


游标是否要求数据库连接保持打开状态

游标是否在事务内部运行,锁定资源直到
“关闭”了吗

是,除非它们是带有HOLD的,在这种情况下,它们会占用其他数据库资源

还有其他我不知道的“陷阱”吗

是的,如上所述

发表评论