有几个设置可能会导致查询规划器在任何情况下都不生成并行查询计划。为了生成任何并行查询计划,必须按指示配置以下设置。
max_parallel_workers_per_gather 必须设置为大于零的值。这是一个更一般原则的特例,即使用的 worker 不应超过通过 max_parallel_workers_per_gather
配置的数量。
此外,系统不能在单用户模式下运行。由于在这种情况下整个数据库系统都作为单个进程运行,因此没有可用的后台 worker。
即使在通常情况下可以生成并行查询计划,如果以下任何一个条件为真,规划器也不会为给定的查询生成它们:
该查询写入任何数据或锁定任何数据库行。如果查询在顶层或 CTE 内包含数据修改操作,则不会为该查询生成任何并行计划。作为例外,以下创建新表并填充它的命令可以使用并行计划来执行查询的底层 SELECT
部分:
CREATE TABLE ... AS
SELECT INTO
CREATE MATERIALIZED VIEW
REFRESH MATERIALIZED VIEW
查询在执行期间可能会被暂停。在系统认为可能会发生部分或增量执行的任何情况下,都不会生成并行计划。例如,使用 DECLARE CURSOR 创建的游标将永远不会使用并行计划。类似地,形式为 FOR x IN query LOOP .. END LOOP
的 PL/pgSQL 循环也永远不会使用并行计划,因为并行查询系统无法验证循环中的代码在并行查询活动时是否可以安全执行。
查询使用任何标记为 PARALLEL UNSAFE
的函数。大多数系统定义的函数都是 PARALLEL SAFE
,但用户定义的函数默认标记为 PARALLEL UNSAFE
。请参阅关于 第 15.4 节 的讨论。
查询在另一个已并行运行的查询内部运行。例如,如果由并行查询调用的函数本身发出 SQL 查询,则该查询将永远不会使用并行计划。这是当前实现的限制,但是删除此限制可能不是理想的,因为它可能会导致单个查询使用非常大量的进程。
即使为特定查询生成了并行查询计划,在执行时也有几种情况下无法并行执行该计划。如果发生这种情况,leader 将完全自行执行 Gather
节点下方的计划部分,几乎就像 Gather
节点不存在一样。如果满足以下任何条件,就会发生这种情况:
由于后台 worker 的总数不能超过 max_worker_processes 的限制,因此无法获取后台 worker。
由于为并行查询目的启动的后台 worker 总数不能超过 max_parallel_workers 的限制,因此无法获取后台 worker。
客户端发送 fetch count 非零的 Execute 消息。请参阅关于扩展查询协议的讨论。由于 libpq 目前没有提供发送此类消息的方法,因此只有在使用不依赖 libpq 的客户端时才会发生这种情况。如果这种情况经常发生,最好在可能会发生这种情况的会话中将 max_parallel_workers_per_gather 设置为零,以避免生成串行运行时可能不是最佳的查询计划。
如果您在文档中发现任何不正确、与您特定功能的体验不符或需要进一步澄清的地方,请使用此表单报告文档问题。