15.1. Como funciona a consulta paralelizada #

Quando o otimizador determina que a consulta paralelizada é a estratégia de execução mais rápida para uma consulta específica, o otimizador cria um plano de consulta que inclui um nó Gather ou Gather Merge. A seguir está um exemplo simples:

EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';

                                     QUERY PLAN
-------------------------------------------------------------------​------------------
 Gather  (cost=1000.00..217018.43 rows=1 width=97)
   Workers Planned: 2
   ->  Parallel Seq Scan on pgbench_accounts  (cost=0.00..216018.33 rows=1 width=97)
         Filter: (filler ~~ '%x%'::text)
(4 linhas)

Em todos os casos, o nó Gather ou Gather Merge terá exatamente um plano filho, que é a parte do plano que será executada em paralelo. Se o nó Gather ou Gather Merge estiver no topo da árvore do plano, a consulta inteira será executada em paralelo. Se estiver em outro lugar na árvore do plano, apenas a parte do plano abaixo deste nó será executada em paralelo. No exemplo acima, a consulta acessa apenas uma tabela, portanto, há apenas um nó de plano diferente do próprio nó Gather; uma vez que este nó do plano é filho do nó Gather, ele será executado em paralelo.

Em Uso do comando EXPLAIN pode ser visto o número de processos auxiliares (chamados aqui de processos trabalhadores) escolhidos pelo planejador. Quando o nó Gather é alcançado durante a execução da consulta, o processo que está implementando a sessão do usuário solicitará um número de processos de trabalho em segundo plano igual ao número de processos trabalhadores escolhidos pelo planejador. O número de processos trabalhadores em segundo plano que o planejador pode considerar usar é limitado a, no máximo, max_parallel_workers_per_gather. O número total de processos trabalhadores em segundo plano que podem existir a qualquer momento é limitado por max_worker_processes e max_parallel_workers. Portanto, é possível que uma consulta paralelizada seja executada com menos processos trabalhadores do que o planejado, ou até mesmo sem nenhum processo trabalhador. O plano ideal pode depender do número de processos trabalhadores disponíveis, portanto, isto pode resultar em um desempenho de consulta ruim. Se esta ocorrência for frequente, considere aumentar as variáveis de configuração max_worker_processes e max_parallel_workers para que mais processos trabalhadores possam ser executados simultaneamente ou, como alternativa, reduzir max_parallel_workers_per_gather, para que o planejador solicite menos processos trabalhadores.

Todo processo trabalhador em segundo plano iniciado com êxito para uma determinada consulta paralelizada irá executar a parte paralela do plano. O líder também irá executar esta parte do plano, mas tem uma responsabilidade adicional: também deverá ler todas as tuplas geradas pelos processos trabalhadores. Quando a parte paralela do plano gera apenas um pequeno número de tuplas, o líder geralmente se comporta como um processo trabalhador adicional, acelerando a execução da consulta. Por outro lado, quando a porção paralela do plano gera um grande número de tuplas, o líder pode estar quase inteiramente ocupado lendo as tuplas geradas pelos processos trabalhadores e executando quaisquer outras etapas de processamento exigidas pelos nós do plano acima do nível do nó Gather ou Gather Merge. Nestes casos, o líder fará muito pouco do trabalho de executar a parte paralela do plano.

Quando o nó na parte superior da parte paralelizada do plano é Gather Merge, em vez de Gather, isto indica que cada processo executando a parte paralelizada do plano está produzindo tuplas de forma ordenada, e que o processo líder está realizando uma mesclagem que preserva a ordem. Em contraste, Gather lê as tuplas dos processos trabalhadores em qualquer ordem conveniente, destruindo qualquer ordenação que possa ter existido.