Существует несколько параметров, из-за которых планировщик запросов ни при каких обстоятельствах не будет формировать план параллельного запроса. Для того чтобы генерировались какие-либо планы параллельных запросов, следующие параметры должны быть настроены указанным образом.
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 никогда не будет использовать
параллельный план. Аналогично, цикл PL/pgSQL вида
FOR x IN query LOOP .. END LOOP никогда не будет использовать
параллельный план, так как подсистема параллельных запросов не может подтвердить,
что код в цикле безопасен для выполнения, пока параллельный запрос
активен.
Запрос использует любую функцию, помеченную как PARALLEL UNSAFE.
Большинство встроенных системных функций имеют пометку PARALLEL SAFE,
но пользовательские функции по умолчанию помечаются как PARALLEL
UNSAFE по умолчанию. См. обсуждение
Раздел 2.12.4.
Запрос выполняется внутри другого запроса, который уже является параллельным. Например, если функция, вызываемая параллельным запросом, сама инициирует SQL-запрос, этот запрос никогда не будет использовать параллельный план. Это является ограничением текущей реализации, однако снятие данного ограничения может быть нежелательным, так как это может привести к тому, что один запрос будет использовать чрезмерно большое количество процессов.
Даже если для конкретного запроса сформирован параллельный план, существует ряд обстоятельств, при которых выполнение этого плана в параллельном режиме будет невозможно. В этом случае ведущий процесс выполнит часть плана, расположенную под Gather
узлом Gather, полностью самостоятельно, как если бы этот Gather узел
отсутствовал. Это произойдет при соблюдении любого из следующих условий:
Невозможно получить фоновые рабочие процессы из-за ограничения, общее количество фоновых рабочих процессов не может превышать max_worker_processes.
Невозможно получить фоновые рабочие процессы из-за ограничения, общее количество фоновых рабочих процессов, запущенных для выполнения параллельный запрос не может превышать max_parallel_workers.
Клиент отправляет сообщение Execute с ненулевым значением параметра fetch count. См. описание протокола расширенных запросов. Поскольку libpq в настоящее время не предоставляет возможности отправки такого сообщения, данная ситуация возможна только при использовании клиента, который не использует libpq. Если это происходит часто, целесообразно установить значение параметра max_parallel_workers_per_gather в ноль в тех сессиях, где это вероятно, чтобы избежать формирования планов запросов, которые могут оказаться субоптимальными при последовательном выполнении.