受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

15.2. 何时可以使用并行查询? #

有几种设置会导致查询规划器在任何情况下都不生成并行查询计划。要让系统能够生成任何并行查询计划,下列设置必须按要求配置。

  • 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。参见 Section 15.4 中的讨论。

  • 该查询运行在另一个已经并行执行的查询内部。例如,如果一个由并行查询调用的函数自己又发出一个 SQL 查询,那么该查询将绝不会使用并行计划。这是当前实现的一个限制,但未必值得移除,因为那样可能导致单个查询使用大量进程。

即使某个特定查询已经生成了并行查询计划,在执行时仍然有若干情况会导致该计划无法并行执行。如果发生这种情况,领导者将完全独自执行 Gather 节点以下的那部分计划,几乎就像 Gather 节点根本不存在一样。满足下列任一条件时,就会出现这种情况:

  • 由于后台工作进程总数不能超过 max_worker_processes,因此无法获得后台工作进程。

  • 由于为并行查询启动的后台工作进程总数不能超过 max_parallel_workers,因此无法获得后台工作进程。

  • 客户端发送了带有非零提取计数的 Execute 消息。请参见扩展查询协议中的讨论。由于 libpq 目前没有提供发送此类消息的方法,因此这种情况只会出现在不依赖 libpq 的客户端中。如果这种情况经常发生,那么在可能发生这种情况的会话中将 max_parallel_workers_per_gather 设置为零可能是个好主意,这样可以避免生成那些在串行运行时可能次优的查询计划。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。