Cuando el optimizador determina que las consultas en paralelo son la estrategia de ejecución más rápida para una consulta en particular, creará un plan de consulta que incluye un nodo Gather o Gather Merge. Aquí tienes un ejemplo sencillo:
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 rows)
En todos los casos, el nodo Gather o
Gather Merge tendrá exactamente un plan hijo (child plan),
que es la parte del plan que se ejecutará en paralelo. Si el nodo
Gather o Gather Merge está en la parte más alta del
árbol de planificación, toda la consulta se ejecutará en paralelo. Si está en algún
otro lugar del árbol, solo la porción del plan por debajo de él se ejecutará en paralelo.
En el ejemplo anterior, la consulta accede solo a una tabla, por lo que solo hay un nodo
de plan aparte del propio nodo Gather; dado que ese nodo de plan es hijo del
nodo Gather, se ejecutará en paralelo.
Usando EXPLAIN, puedes ver el número de
trabajadores (workers) elegidos por el planificador. Cuando se alcanza el nodo
Gather durante la ejecución de la consulta, el proceso que implementa la
sesión del usuario solicitará un número de procesos trabajadores en
segundo plano (background workers) igual al número de trabajadores elegido por el planificador.
El número de trabajadores en segundo plano que el planificador considerará usar está limitado
a como máximo max_parallel_workers_per_gather. El número total
de trabajadores en segundo plano que pueden existir simultáneamente está limitado tanto por
max_worker_processes como por
max_parallel_workers. Por lo tanto, es posible que una
consulta en paralelo se ejecute con menos trabajadores de los planificados, o incluso sin
ningún trabajador. El plan óptimo puede depender del número de trabajadores disponibles,
por lo que esto puede resultar en un bajo rendimiento de la consulta. Si esto ocurre con
frecuencia, considera aumentar max_worker_processes y
max_parallel_workers para que se puedan ejecutar más trabajadores de forma
simultánea, o bien reducir max_parallel_workers_per_gather para que el
planificador solicite menos trabajadores.
Cada proceso trabajador en segundo plano que se inicia con éxito para una consulta en paralelo
dada ejecutará la parte paralela del plan. El líder también ejecutará esa parte del plan, pero
tiene una responsabilidad adicional: también debe leer todas las tuplas generadas por los
trabajadores. Cuando la porción paralela del plan genera solo un número pequeño de tuplas, el
líder a menudo se comportará de manera muy similar a un trabajador adicional, acelerando la
ejecución de la consulta. Por el contrario, cuando la porción paralela del plan genera una
gran cantidad de tuplas, el líder puede estar ocupado casi por completo leyendo las tuplas
generadas por los trabajadores y realizando los pasos de procesamiento adicionales requeridos
por los nodos del plan por encima del nivel del nodo Gather o del nodo
Gather Merge. En tales casos, el líder hará muy poco trabajo de la
ejecución de la porción paralela del plan.
Cuando el nodo en la parte superior de la porción paralela del plan es
Gather Merge en lugar de Gather, indica que
cada proceso que ejecuta la porción paralela del plan está produciendo
tuplas en orden ordenado, y que el líder está realizando una fusión que preserva
el orden. Por el contrario, Gather lee las tuplas de los
trabajadores en el orden que le resulte conveniente, destruyendo cualquier orden de
clasificación que pudiera haber existido.