使用非常大的结果集查询 Postgresql

Posted

技术标签:

【中文标题】使用非常大的结果集查询 Postgresql【英文标题】:Querying Postgresql with a very large result set 【发布时间】:2010-06-15 22:18:10 【问题描述】:

在一个应用程序中,我需要查询一个 Postgres 数据库,我希望结果集中有数千万甚至数亿行。我可能会每天执行一次此查询,甚至更频繁。查询本身相对简单,但可能涉及一些 JOIN。

我的问题是:Postgres 在避免为结果集的每一行搜索磁盘方面有多聪明?考虑到硬盘寻道所需的时间,这可能会非常昂贵。

如果这不是问题,Postgres 如何避免它?它如何知道如何在磁盘上布置数据,以便响应此查询以有效的方式流式传输?

【问题讨论】:

希望有人能评论一下 PostgreSQL 的硬解析和软解析能力... 在“硬”与“软”解析中,每个 PostgreSQL 查询都是硬解析,除非它是一个 PREPARED 语句,在这种情况下它是预先解析的(当准备好时)。 Postgres 没有查询缓存。 【参考方案1】:

当 PostgreSQL analyzes your data 时,查询计划器计算和使用的统计数据之一是字段或索引中值的排序与磁盘上的顺序之间的 correlation

物理行排序和列值的逻辑排序之间的统计相关性。范围从 -1 到 +1。当值接近 -1 或 +1 时,由于减少了对磁盘的随机访问,估计列上的索引扫描比接近零时便宜。 (如果列数据类型没有

index cost estimation functions 也计算一个相关性

indexCorrelation 应该设置为索引顺序和表顺序之间的相关性(范围在 -1.0 和 1.0 之间)。这用于调整从父表获取行的成本估算。

我不确定,但我假设规划器在确定是否可以通过执行表以较低成本完成从表中读取的行数时使用来自各种可能计划的相关值扫描,使用顺序 io(可能加入同一个表的另一个并发扫描),过滤所需的行,或索引扫描,以及其结果查找。

PostgreSQL 不会根据任何特定的键对表进行排序,但可以使用CLUSTER 命令以特定的索引顺序定期重新创建它们(如果数据到簇与索引值顺序的相关性较低)。

PostgreSQL 能够有效地收集一组需要检索的磁盘块,然后按物理顺序获取它们以减少查找。它通过位图扫描来做到这一点。 Release Notes for 8.1说:

位图扫描即使使用单个索引也很有用,因为它们减少了所需的随机访问量;位图索引扫描对于检索整个表的相当大的部分是有效的,而普通索引扫描则不然。


编辑:我的意思是提到 planner cost contants seq_page_costrandom_page_cost 通知计划者执行磁盘页面获取的相对成本,这是一系列顺序获取的一部分,而不是非顺序获取-获取的磁盘页面。

【讨论】:

以上是关于使用非常大的结果集查询 Postgresql的主要内容,如果未能解决你的问题,请参考以下文章

数据冗余 - 加入大型结果集

如何将一个非常大的 lucene 结果集连接到一个真正的大型 sql 表 [10 的百万行]

查询或合并一对多关系而不复制结果条目

好主意/坏主意:在非常大的数据集上使用 Qt 的 QSet?

postgresql 查询中的大结果集

Sql中in和exists详解