在一个应用程序中,我需要查询一个 Postgres 数据库,我希望结果集中有数千万甚至数亿行。我可能每天执行一次此查询,甚至更频繁。查询本身相对简单,尽管可能涉及一些 JOIN。
我的问题是:Postgres 在避免为结果集的每一行绕过磁盘寻找方面有多聪明?考虑到硬盘寻道所需的时间,这可能会非常昂贵。
如果这不是问题,Postgres 如何避免它?它如何知道如何在磁盘上布置数据,以便响应此查询以高效的方式将数据流出?
最佳答案
当 PostgreSQL analyzes your data ,查询计划器计算和使用的统计信息之一是 correlation在字段或索引中的值排序与磁盘上的顺序之间。
Statistical correlation between physical row ordering and logical ordering of the column values. This ranges from -1 to +1. When the value is near -1 or +1, an index scan on the column will be estimated to be cheaper than when it is near zero, due to reduction of random access to the disk. (This column is NULL if the column data type does not have a < operator.)
index cost estimation functions还计算相关性:
The indexCorrelation should be set to the correlation (ranging between -1.0 and 1.0) between the index order and the table order. This is used to adjust the estimate for the cost of fetching rows from the parent table.
我不确定,但我假设计划者在确定是否可以通过执行表以较低的成本完成要从表中读取的行数时使用来自各种可能计划的相关值扫描,使用顺序 io(可能加入同一表的另一个并发扫描),过滤所需的行,或索引扫描,及其结果查找。
PostgreSQL 不会根据任何特定的键对表进行排序,但可以使用 CLUSTER 以特定的索引顺序定期重新创建它们命令(这会很慢,如果要集群的数据与索引值顺序的相关性较低,则每行都要进行一次磁盘搜索)。
PostgreSQL 能够有效地收集一组需要检索的磁盘 block ,然后按物理顺序获取它们以减少查找。它通过位图扫描来做到这一点。 Release Notes for 8.1说:
Bitmap scans are useful even with a single index, as they reduce the amount of random access needed; a bitmap index scan is efficient for retrieving fairly large fractions of the complete table, whereas plain index scans are not.
编辑:我想提一下 planner cost contants seq_page_cost
和 random_page_cost
告知计划者执行作为一系列顺序获取一部分的磁盘页面获取与非顺序获取磁盘的相对成本页面。
关于sql - 使用非常大的结果集查询 Postgresql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3049470/