Postgresql 中文操作指南

15.3. Parallel Plans #

由于每个工作程序都会完整地执行计划的并行部分,因此无法只采用一个普通查询计划并使用多个工作程序运行它。每个工作程序都会生成输出结果集的一个完整副本,因此查询不会比正常情况下运行得更快,但会产生不正确的结果。相反,计划的并行部分必须是查询优化器内部所称 partial plan 的部分;也就是说,它必须以这样的方式构建,以至于执行该计划的每个进程只生成输出行的一个子集,从而保证每个必需的输出行都恰好由一个协作进程生成。通常,这意味着查询的驱动表上的扫描必须是并行扫描。

15.3.1. Parallel Scans #

目前支持以下类型的具有并行感知能力的表扫描。

其他扫描类型(例如非 btree 索引的扫描)将来可能会支持并行扫描。

15.3.2. Parallel Joins #

就像在非并行计划中一样,可以使用嵌套循环、哈希联接或合并联接将驱动表与一个或多个其他表联接。联接的内部可以是任何类型的非并行计划,只要规划程序支持该计划,并且在并行工作程序中运行该计划是安全的。根据联接类型,内部也可能是并行计划。

15.3.3. Parallel Aggregation #

PostgreSQL 通过两个阶段聚合来支持并行聚合。首先,参与查询并行部分的每个进程都执行一个聚合步骤,为该进程所知的每个组生成一个部分结果。这在计划中反映为 Partial Aggregate 节点。其次,部分结果通过 GatherGather Merge 传输到领导者。最后,领导者重新聚合所有工作程序中的结果以生成最终结果。这在计划中反映为 Finalize Aggregate 节点。

由于 Finalize Aggregate 节点在领导者进程上运行,因此与输入行数相比生成大量组的查询对于查询规划程序来说似乎不太有利。例如,在最坏的情况下,Finalize Aggregate 节点看到的组数可能多达 Partial Aggregate 阶段所有工作程序进程看到的输入行数。对于这种情况,使用并行聚合显然不会带来性能优势。在规划过程中,查询规划程序会考虑这一点,并且在这种情况下不太可能选择并行聚合。

并非在所有情况下都支持并行聚合。每个聚合必须为 safe 以实现并行性,并且必须有一个组合函数。如果聚合具有 internal 类型的转换状态,则它必须具有序列化和反序列化函数。有关更多详细信息,请参见 CREATE AGGREGATE 。如果聚合函数调用包含 DISTINCTORDER BY 子句,或者当查询涉及 GROUPING SETS 时,不支持并行聚合,也不适用于有序集合聚合。只有当查询中涉及的所有联接也是计划的并行部分时,才可以执行并行聚合。

15.3.4. Parallel Append #

每当 PostgreSQL 需要将来自多个源的行合并到单个结果集中时,它都会使用 AppendMergeAppend 计划节点。这种情况通常发生在实现 UNION ALL 或扫描分区表时。这些节点可以在并行计划中使用,就像在任何其他计划中一样。然而,在一个并行计划中,规划程序可能会改为使用 Parallel Append 节点。

Append 节点用于并行计划中时,每个进程都会按它们出现的顺序执行子计划,以便所有参与进程协同执行第一个子计划直到它完成,然后在大致同一时间移动到第二个计划。当改为使用 Parallel Append 时,执行器会尽可能均匀地将参与进程分布到其子计划中,以便同时执行多个子计划。这避免了争用,还避免了在从未执行子计划的进程中支付子计划的启动成本。

此外,与只能在并行计划中使用时具有部分子项的常规 Append 节点不同,Parallel Append 节点可以同时具有部分和非部分子项。非部分子项将只由一个进程扫描,因为扫描它们多次会产生重复结果。因此,涉及追加多个结果集的计划即使在没有有效的局部计划时也能实现粗粒度并行处理。例如,考虑一个对分区表的查询,该查询只能通过使用不支持并行扫描的索引来有效实现。规划程序可能会选择常规 Index Scan 计划的 Parallel Append;每个单独的索引扫描都必须由一个进程执行完毕,但是不同的进程可以同时执行不同的扫描。

可使用 enable_parallel_append 禁用此功能。

15.3.5. Parallel Plan Tips #

如果预期执行但并未生成并行计划的查询,则可以尝试减小 parallel_setup_costparallel_tuple_cost 。当然,该计划可能比计划程序首选的串行计划慢,但这并不总是如此。即使将这些设置的值设得非常小(例如,将它们都设置为零),仍然无法获得并行计划,则可能是查询计划程序无法为查询生成并行计划的原因。请参阅 Section 15.2Section 15.4 了解可能出现这种情况的原因。

在执行并行计划时,您可以使用 EXPLAIN (ANALYZE, VERBOSE) 为每个计划节点显示每个工作程序的统计信息。这可能有助于确定工作是否在所有计划节点之间均匀分布,并且更普遍地了解计划的性能特征。