# 15.3.平行计划

15.3.1. 平行扫描

15.3.2. 平行连接

15.3.3. 并行聚合

15.3.4. 并行追加

15.3.5. 并行计划提示

因为每个辅助人员都执行计划的并行部分直到完成,所以不可能简单地获取一个普通的查询计划并使用多个辅助人员运行它。每个工作者都会生成输出结果集的完整副本,因此查询的运行速度不会比正常情况快,但会生成不正确的结果。相反,计划的并行部分必须是查询优化器内部已知的部分计划; 也就是说,它的构造必须确保执行计划的每个进程只生成输出行的一个子集,从而确保每个所需的输出行都由一个协作进程生成。通常,这意味着对查询驱动表的扫描必须是并行感知扫描。

# 15.3.1.平行扫描

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

  • 在一个并行顺序扫描,表的块将在协作进程中划分。块一次分发一个,因此对表的访问保持顺序。

  • 在一个并行位图堆扫描,一个流程被选为领导者。该过程对一个或多个索引进行扫描,并生成一个位图,指示需要访问哪些表块。然后,像并行顺序扫描一样,将这些块划分到协作进程中。换句话说,堆扫描是并行执行的,但底层索引扫描不是。

  • 在一个并行索引扫描仅并行索引扫描,协作进程轮流从索引中读取数据。目前,只有btree索引支持并行索引扫描。每个进程将声明一个索引块,并扫描并返回该块引用的所有元组;其他进程可以同时从不同的索引块返回元组。并行btree扫描的结果在每个工作进程内按排序顺序返回。

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

# 15.3.2.平行连接

就像在非并行计划中一样,可以使用嵌套循环、哈希连接或合并连接将驱动表连接到一个或多个其他表。联接的内侧可以是任何类型的非并行计划,如果在并行工作程序中运行是安全的,则该计划由计划程序支持。根据连接类型,内侧也可能是平行平面。

  • 在一个嵌套循环联接,内侧始终不平行。尽管它是完整执行的,但如果内部是索引扫描,这是有效的,因为外部元组以及在索引中查找值的循环在协作进程中被划分。

  • 在一个使用融合,内部始终是一个非平行计划,因此完全执行。这可能效率低下,尤其是在必须执行排序的情况下,因为工作和结果数据在每个协作过程中都是重复的。

  • 在一个散列连接(没有“parallel”前缀),每个协作进程都会完整地执行内部,以构建哈希表的相同副本。如果哈希表太大或计划太昂贵,这可能会导致效率低下。在一个并行哈希连接,内侧是一个并行散列这将构建共享哈希表的工作划分为协作进程。

# 15.3.3.并行聚合

PostgreSQL通过分两个阶段进行聚合来支持并行聚合。首先,参与查询并行部分的每个进程执行一个聚合步骤,为该进程知道的每个组生成一个部分结果。这一点作为一个整体反映在计划中部分骨料节点。第二,部分结果通过聚集聚集合并.最后,领导重新汇总所有员工的结果,以产生最终结果。这一点作为一个整体反映在计划中最终确定骨料节点。

因为最终确定骨料节点在leader进程上运行,与输入行的数量相比,生成相对较多组的查询对查询计划器来说似乎不太有利。例如,在最坏的情况下,用户看到的组数最终确定骨料节点的数量可以与中所有工作进程看到的输入行的数量相同部分骨料阶段在这种情况下,使用并行聚合显然不会带来性能方面的好处。查询计划器在计划过程中会考虑到这一点,在这种情况下不太可能选择并行聚合。

并非所有情况下都支持并行聚合。每个骨料必须安全对于并行性,必须具有合并功能。如果聚合具有类型为的转换状态内部的,它必须具有序列化和反序列化功能。看见创建聚合更多细节。如果任何聚合函数调用包含不同的订购人子句,当查询涉及分组集。仅当查询中涉及的所有联接也是计划并行部分的一部分时,才可以使用它。

# 15.3.4.并行追加

每当PostgreSQL需要将来自多个源的行组合到一个结果集中时,它都会使用追加合并附加计划节点。这通常发生在实现联合所有或者在扫描分区表时。这样的节点可以在并行计划中使用,就像它们可以在任何其他计划中使用一样。然而,在平行计划中,规划者可以使用并行追加节点。

追加节点用于并行计划中,每个进程将按其出现的顺序执行子计划,以便所有参与进程协作执行第一个子计划,直到完成,然后大约同时移动到第二个计划。当并行追加相反,执行者将在其子计划中尽可能均匀地分布参与过程,以便同时执行多个子计划。这避免了争用,也避免了在从未执行子计划的过程中支付子计划的启动成本。

而且,和普通人不同追加节点,在并行计划中使用时只能有部分子节点并行追加节点可以同时具有部分和非部分子计划。非部分儿童将只通过一个过程进行扫描,因为多次扫描会产生重复的结果。因此,涉及附加多个结果集的计划可以实现粗粒度并行,即使在没有有效的部分计划时也是如此。例如,考虑对只能通过不支持并行扫描的索引有效实现的分区表的查询。规划者可以选择并行追加普通的索引扫描计划;每个单独的索引扫描都必须由一个进程执行到完成,但不同的进程可以同时执行不同的扫描。

使可能_平行的_追加可用于禁用此功能。

# 15.3.5.并行计划提示

如果预期这样做的查询没有生成并行计划,可以尝试减少平行的_设置_费用平行的_元组_费用.当然,这个计划可能会比规划师喜欢的系列计划慢,但情况并非总是如此。如果即使这些设置的值非常小(例如,在将它们都设置为零后),也无法获得并行计划,那么查询计划器无法为您的查询生成并行计划可能是有原因的。看见第15.2节第15.4节了解为什么会出现这种情况。

执行并行计划时,可以使用解释(分析,详细)显示每个计划节点的每个工作人员统计信息。这可能有助于确定工作是否在所有计划节点之间均匀分布,以及更广泛地理解计划的性能特征。