2024年9月26日: PostgreSQL 17 发布!
支持版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不支持的版本:11 / 10 / 9.6

15.1. 并行查询工作原理 #

当优化器确定并行查询是特定查询最快的执行策略时,它将创建一个包含GatherGather Merge 节点的查询计划。以下是一个简单的示例

EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
                                     QUERY PLAN
-------------------------------------------------------------------​------------------
 Gather  (cost=1000.00..217018.43 rows=1 width=97)
   Workers Planned: 2
   ->  Parallel Seq Scan on pgbench_accounts  (cost=0.00..216018.33 rows=1 width=97)
         Filter: (filler ~~ '%x%'::text)
(4 rows)

在所有情况下,GatherGather Merge 节点都将只有一个子计划,该子计划将并行执行。如果 GatherGather Merge 节点位于计划树的最顶端,那么整个查询将并行执行。如果它位于计划树中的其他位置,那么只有它下面的计划部分将并行运行。在上面的示例中,查询仅访问一个表,因此除了 Gather 节点本身之外,只有一个计划节点;由于该计划节点是 Gather 节点的子节点,因此它将并行运行。

使用 EXPLAIN,您可以看到规划器选择的 worker 数量。当在查询执行期间到达 Gather 节点时,实现用户会话的进程将请求数量等于规划器选择的 worker 数量的后台 worker 进程。规划器将考虑使用的后台 worker 数量限制为最多 max_parallel_workers_per_gather。可以同时存在的后台 worker 总数受 max_worker_processesmax_parallel_workers 的限制。因此,并行查询可能以少于计划的 worker 运行,甚至完全没有 worker。最佳计划可能取决于可用的 worker 数量,因此这会导致查询性能低下。如果这种情况经常发生,请考虑增加 max_worker_processesmax_parallel_workers,以便可以同时运行更多 worker,或者减少 max_parallel_workers_per_gather,以便规划器请求更少的 worker。

为给定的并行查询成功启动的每个后台 worker 进程都将执行计划的并行部分。leader 也将执行计划的该部分,但它还有另外一项责任:它还必须读取 worker 生成的所有元组。当计划的并行部分仅生成少量元组时,leader 通常会表现得非常像一个额外的 worker,从而加速查询执行。相反,当计划的并行部分生成大量元组时,leader 可能几乎完全被读取 worker 生成的元组和执行 Gather 节点或 Gather Merge 节点级别以上计划节点所需的任何进一步处理步骤所占用。在这种情况下,leader 在执行计划的并行部分的工作中几乎不会做任何事情。

当计划的并行部分顶部的节点是 Gather Merge 而不是 Gather 时,表示每个执行计划的并行部分的进程都按排序顺序生成元组,并且 leader 正在执行一个保持顺序的合并。相反,Gather 以任何方便的顺序从 worker 读取元组,破坏任何可能存在的排序顺序。

提交更正

如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步说明,请使用 此表格 报告文档问题。