Общий параллелизм с PostgreSQL CTE - PullRequest
0 голосов
/ 18 октября 2019

Я работаю с некоторыми большими данными, и необходимо получать параллельные планы в моих запросах. Мне также очень нравится использовать CTE для выражения моих запросов, но, следуя документации PostgreSQL, я не уверен, что CTE накладывают серьезные ограничения на параллелизм или нет.

Здесь , CTE ивременные таблицы помечены как «параллельные ограничения», где «параллельные ограничения» определены как

Операция с параллельными ограничениями - это операция, которая не может быть выполнена в параллельном работнике, но может быть выполнена в ведущемв то время как используется параллельный запрос.

Здесь , описание параллельных ограничений для CTE считается немного другим:

Еслизапрос содержит операцию изменения данных либо на верхнем уровне, либо внутри CTE, параллельные планы для этого запроса не будут создаваться.

В моем случае у меня нет данных, изменяющих данныеоперации.

В какой степени CTE ограничат качество моего параллельного плана, если вообще?

Если честно, у меня возникли некоторые трудности с пониманиемПоследствия первого определения. Поскольку CTE могут быть материализованы как временные таблицы, то я уверен, что это влияние еще более актуально. И второе определение предполагает, что ограничения параллелизма CTE связаны только с операциями изменения данных.

1 Ответ

0 голосов
/ 18 октября 2019

Использование CTE - это нормально и в большинстве случаев не будет препятствовать параллельному выполнению.

Ограничение состоит в том, что CTE находится в состоянии частного процесса параллельного лидера, поэтому параллельные работники не могут его сканировать. Кроме этого, PostgreSQL с радостью сгенерирует параллельный план.

Так что можно избежать запросов типа

WITH a AS (SELECT ...)
SELECT ... FROM a JOIN b ...

, если вы хотите, чтобы объединение было распараллелено. Запрос внутри CTE может быть распараллелен (я думаю), и сканирование b может быть распараллелено также.

Для оптимального распараллеливания вы можете попробовать переписать запрос как

SELECT ...
FROM (SELECT ...) AS a
   JOIN b ...
...