在PostgreSQL中使用"Cursors"进行分页

Chr*_*row 20 postgresql pagination paginate

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

想知道使用游标是使用PostgreSQL实现"分页"的好方法.

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

但是,我对游标的工作方式以及如何以及何时应该使用游标有点模糊:

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

非常感谢!

Cra*_*ger 29

在使用大型数据集的较小Intranet应用程序中,游标是分页的合理选择,但您需要准备在超时后丢弃它们.用户喜欢闲逛,去吃午餐,去度假两周等,并让他们的应用程序继续运行.如果它是一个基于网络的应用程序,甚至还有"运行"是什么以及如何判断用户是否还在的问题.

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

游标有几个成本.如果光标不是WITH HOLD,则必须保持事务处于打开状态.打开事务可以防止autovacuum正常工作,导致表膨胀和其他问题.如果声明游标WITH HOLD并且事务未保持打开,则必须支付实现和存储可能较大的结果集的成本 - 至少,我认为这是保持游标的工作方式.替代方案同样糟糕,保持事务隐式打开,直到游标被销毁并阻止行被清除.

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

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

在一般情况下,尽管事实上,它可以是相当低效的,LIMIT并且OFFSET可以更好的解决方案.它往往是更好的搜索主键,而不是使用OFFSET,虽然.

顺便说一下,你正在查看PL/pgSQL中游标的文档.您需要此作业的普通SQL级游标.


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

是.

游标是否在事务中运行,锁定资源直到它们"关闭"?

是,除非它们是WITH HOLD,在这种情况下,它们消耗其他数据库资源.

还有其他我不知道的"陷阱"吗?

是的,正如上面应该解释的那样.