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

标签 sql postgresql

在一个应用程序中,我需要查询一个 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_costrandom_page_cost 告知计划者执行作为一系列顺序获取一部分的磁盘页面获取与非顺序获取磁盘的相对成本页面。

关于sql - 使用非常大的结果集查询 Postgresql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3049470/

相关文章:

postgresql - Liquibase/Spring Boot/Postgres - 架构名称不起作用

postgresql - Postgres游标

sql - 如何在 Ruby on Rails 中编写任意 SQL 查询?

mysql - SQL order by,放在哪里?

c# - 如何在 Npgsql.EntityFrameworkCore 中查询具有 JSON 数组的列

sql - PostgreSQL 中的 date_trunc 5 分钟间隔

postgresql - 最长公共(public)子序列 Postgresql

sql - SELECT 语句中带有 if 比较的 TSQL CASE

mysql - 来自多个表 MySql 的单个查询

sql - 窗口函数 - 带重置的运行总计