有几个设置会导致查询规划器在任何情况下都不会生成并行查询计划。为了能够生成任何并行查询计划,必须按指示配置以下设置。
max_parallel_workers_per_gather 必须设置为大于零的值。这是更普遍原则的一个特例,即不应使用比通过 max_parallel_workers_per_gather
配置的更多工作进程。
此外,系统不能处于单用户模式。在这种情况下,由于整个数据库系统作为一个单一进程运行,因此没有可用的后台工作进程。
即使通常可以生成并行查询计划,但如果满足以下任一条件,规划器也不会为给定查询生成它们:
查询会写入任何数据或锁定任何数据库行。如果查询在顶层或 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 查询,则该查询永远不会使用并行计划。这是当前实现的一个限制,但移除此限制可能并不理想,因为它可能导致单个查询使用非常多的进程。
即使为特定查询生成了并行查询计划,在执行时也有几种情况会导致无法并行执行该计划。如果发生这种情况,领导者将完全由自己执行 Gather
节点下方的计划部分,几乎就像 Gather
节点不存在一样。如果满足以下任何条件,就会发生这种情况:
由于总后台工作进程数不能超过 max_worker_processes 的限制,无法获得后台工作进程。
由于为并行查询目的启动的总后台工作进程数不能超过 max_parallel_workers 的限制,无法获得后台工作进程。
客户端发送的 Execute 消息的 fetch count 非零。请参见 扩展查询协议 的讨论。由于 libpq 目前不提供发送此类消息的方法,因此只有在使用不依赖 libpq 的客户端时才会发生这种情况。如果这种情况频繁发生,那么在可能发生这种情况的会话中,将 max_parallel_workers_per_gather 设置为零可能是一个好主意,这样可以避免生成在串行运行时可能不是最优的查询计划。
如果您在文档中发现任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表格 报告文档问题。