psycopg2:如果表的内存不足,PostgreSQL会在磁盘上存储表的副本吗

psycopg2:如果表的内存不足,PostgreSQL会在磁盘上存储表的副本吗,postgresql,psycopg2,Postgresql,Psycopg2,我正在一台内存为2 gb的计算机上对4.89亿行102 gb运行以下查询: select * from table order by x, y, z, h, j, l; 我使用的psycopg2带有服务器游标的唯一名称,一次可以获取30000行 显然,查询的结果无法保留在内存中,但我的问题是,以下查询集是否会同样快: select * into temp_table from table order by x, y, z, h, j, l; select * from temp_table

我正在一台内存为2 gb的计算机上对4.89亿行102 gb运行以下查询:

select * from table order by x, y, z, h, j, l;
我使用的psycopg2带有服务器游标的唯一名称,一次可以获取30000行

显然,查询的结果无法保留在内存中,但我的问题是,以下查询集是否会同样快:

select * into temp_table from table order by x, y, z, h, j, l;
select * from temp_table
这意味着我将使用一个temp_表来存储排序结果,并从该表中取回数据

提出此问题的原因是,如果使用psql手动运行,则只需36分钟即可完成,但在使用psycopg2执行查询时,要获取前30000行却需要8个多小时的时间

如果要按块获取此表并进行排序,则需要创建索引。如果没有这样的索引,则每次提取都需要对整个表进行排序。您的光标可能会为每一行获取的数据对该表进行一次排序-等待红巨星太阳可能会更快结束… 在tablename x,y,z,h,j,l上创建索引tablename\u order\u idx

如果您的表数据相对稳定,那么您应该使用此索引来创建它。这样就可以获取表数据,而无需在磁盘上进行太多搜索。 使用tablename\u order\u idx集群tablename

如果您想要以块的形式获取数据,您不应该使用游标,因为它总是一次工作一行。你应使用: 按x、y、z、h、j、l的顺序从表名中选择* 限制30000偏移44*30000


在pyscopg2中几乎肯定会出现减速,我假设您的光标是pyscopg2.cursor。您所说的订购差异可能会改善36分钟部分,但不会改善8小时部分!pyscopg2与排序无关,它只向服务器发送消息并接收结果。我会尽量减少30000个数字,看看你什么时候开始得到缓慢的结果。你的问题很模糊,所以很难说为什么psycopg2和服务器端游标不适合你。但是不,将它们全部插入一个临时表,然后扫描这个表只会使您的速度减慢。Tometzky说得对-在排序列上创建索引。-1您不需要“创建索引”,因为查询“如果使用psql手动运行,只需36分钟即可完成”。“集群”也是如此。使用“limit”和“offset”是完全错误的——即使在您相当长的查询过程中根本没有更新,谁能说订单中没有联系?如果在30000位出现平局,你能确定postgres会以同样的方式为你的第一个和第二个“区块”打破平局吗。不。@JackPDouglas:不是很有建设性的批评-请提供更好的解释。限制和偏移方法要求主键是order子句中的最后一列。当为这一系列查询选择可序列化事务级别时,另一个事务中的更新没有问题。限制和偏移方法要求主键是order子句中的最后一列--您是指postgres以外的其他数据库吗?不确定可序列化隔离级别的一种或另一种方法-至少您是这样也许应该在你的回答中提到它——但这是真的吗?@JackPDouglas:我的意思是,为了从限制/偏移中获得有意义的结果,你必须严格地对数据排序,这意味着你需要例如主键作为order子句中的最后一列。它不强制执行,但在其他情况下不起作用。可序列化隔离足以读取只读事务中数据的一致快照。否则,不可能执行一致的备份。也许我应该在我的回答中提到这一切,但嘿,我们都是时间饥渴。