PostgreSQL中一种高效的大表并行阅读方法

fykwrbwg  于 6个月前  发布在  PostgreSQL
关注(0)|答案(1)|浏览(47)

考虑这样一种情况,当有一个非常大的表(高达几TB),并且出于某种原因,应用程序希望扫描整个表。在应用程序和PostgreSQL服务器端都有多个CPU核心,因此它给我们带来了将表分成多个部分并在并行线程中并行阅读它们的想法。实现这一点的最佳方法是什么?
像这样用OFFSET / LIMIT模拟表的“分页”有意义吗?

SELECT * FROM table LIMIT 1000000 OFFSET 0
SELECT * FROM table LIMIT 1000000 OFFSET 1000000
SELECT * FROM table LIMIT 1000000 OFFSET 2000000
(...)

字符串
因此每个SELECT将在不同的应用程序线程中执行。
或者也许值得尝试使用PostgreSQL原生table partitioning,这样每个表分区(实际上是一个不同的表)都可以独立读取?
另一个重要的问题是一致性。当然,在扫描过程中,表可能会发生变化。PostgreSQL是否为独立的SELECT s提供任何类型的事务,使它们能够使用表的一致视图,而不需要后续请求带来的数据?

cedebl8k

cedebl8k1#

PostgreSQL支持parallel queries
PostgreSQL可以设计出可以利用多个CPU的查询计划,以便更快地回答查询。这个特性被称为并行查询。
但并行化并不是一颗灵丹妙药。
许多查询无法从并行查询中受益,这要么是由于当前实现的限制,要么是因为没有任何可以想象的查询计划比串行查询计划更快。然而,对于可以受益的查询,并行查询的加速通常非常显著。许多查询在使用并行查询时可以运行两倍以上的速度,有些查询的运行速度可以快四倍甚至更多。处理大量数据但只向用户返回几行的查询通常受益最多。
我不打算详细介绍,这都是关于如何配置Postgres以使用并行worker并进行并行seq扫描的in the docs
在某种程度上,不管你有多少CPU,你都要遇到磁盘I/O的限制。即使是最好的SSD也只能读取10 GB/s,几TB至少需要几分钟。最好是问一下你是否可以避免seq扫描表。
或者也许值得尝试使用PostgreSQL本地表分区,这样每个表分区(实际上是一个不同的表)都可以独立读取?
有可能,但表分区也不是一个神奇的性能子弹。没有更多的细节我不能说。
第三种选择是将这个庞大的数据块移动到针对这些大型查询优化的data warehouse中。

相关问题