小编Mik*_*ton的帖子

在Postgres中正确使用游标来获得非常大的结果集

我的问题的简短版本:

如果我在我的客户端代码中持有一个游标引用天文数字巨大的结果集,那么发出"FETCH ALL FROM cursorname"作为我的下一个命令会是荒谬的(即完全失去游标的点)吗?或者当我消耗它时,这会慢慢地将数据流回给我(至少在原则上,假设我有一个写得很好的驱动程序坐在我和Postgres之间)?

更多详情

如果我完全理解了事情,那么Postgres游标真的可以处理以下问题[即使它们可以被用来(滥用?)用于其他事情,例如从一个函数返回多个不同的结果集]:

注意:RETURN NEXT和RETURN QUERY的当前实现在从函数返回之前存储整个结果集,如上所述.这意味着如果PL/pgSQL函数产生非常大的结果集,性能可能会很差:数据将写入磁盘以避免内存耗尽,但在生成整个结果集之前,函数本身不会返回.

(参考:https://www.postgresql.org/docs/9.6/static/plpgsql-control-structures.html)

但是(再次,如果我理解正确)当你编写一个返回游标的函数时,整个查询不会被缓冲到内存(和磁盘)之前,函数的用户可以开始消耗任何东西,但是结果可以被消耗掉一点一滴.(设置和使用游标的开销更多,但是为了避免对非常大的结果集进行大量缓冲区分配,这是值得的.)

(参考:https://www.postgresql.org/docs/9.6/static/plpgsql-cursors.html#AEN66551)

我想了解这是如何通过线路连接到Postgres服务器上的SELECTS和FETCHES.

在所有情况下,我都在讨论从客户端代码中获取结果,这些客户端代码在幕后的套接字上与Postgres进行通信(实际上在我的情况下使用Npgsql库).

Q1:如果我尝试执行"SELECT*FROM AstronomicallyLargeTable"作为我对Postgres的唯一命令,该怎么办?是否会为整个选择分配所有内存,然后开始向我发送数据?或者它(有效地)生成自己的游标并一次一点地回流数据(在服务器上没有大量额外的缓冲区分配)?

Q2:如果我已经有一个天文大的结果集的游标引用(比如因为我已经完成了一次往返,从一些函数中取回了游标引用),然后我执行"FETCH ALL FROM cursorname",该怎么办? Postgres的电线?这是愚蠢的,因为它会在向Postgres服务器发送任何内容之前为Postgres服务器上的所有结果分配所有内存吗?或者"FETCH ALL FROM cursorname"实际上是按照我的意愿工作,在我消耗数据的同时慢慢地将数据流回来,而Postgres服务器上没有发生任何大量的缓冲区分配?

编辑:进一步澄清

我问的是一个案例,我知道我的数据访问层将数据从服务器一次一行地传输到我一行(所以没有大的客户端缓冲区涉及到那里,无论数据流是多长时间)我也在哪里知道我自己的应用程序一次消耗一行数据然后丢弃它(因此也没有客户端缓冲区).我绝对不想将所有这些行提取到客户端内存中,然后用它们做一些事情.我看到那将是完全愚蠢的!

所以我认为所有的问题(对于刚才描述的用例)都是关于PostgreSQL开始流的时间和它将分配多少内存缓冲区的问题FETCH ALL.IF(并且它是一个很大的'IF'...)PostgreSQL 在开始之前不会为所有行分配一个巨大的缓冲区,如果它一次一行地将行流回Npgsql,快速启动,那么我相信(但请告诉我为什么/如果我错了)还有一个明确的用例FETCH ALL FROM cursorname!

postgresql cursor

9
推荐指数
1
解决办法
6854
查看次数

获取当前版本 Windows 10 的 dfsutil?

dfsutil在工作站上用于检查客户端订阅的 DFS 共享的情况非常有用,例如通过运行dfsutil /pktinfo.

对于 2018 年 10 月之前的 Windows 10,dfsutil可以作为Windows 10 的 RSAT 工具的一部分进行下载,但如何获取dfsutil当前版本的 Windows 10?

replication windows-10

4
推荐指数
1
解决办法
1万
查看次数

标签 统计

cursor ×1

postgresql ×1

replication ×1

windows-10 ×1