Usar la ejecución paralela para la parte SELECT de una consulta INSERT INTO ... SELECT puede mejorar el rendimiento de las consultas de AlloyDB para PostgreSQL, en especial para las tablas particionadas y las consultas complejas.
Al paralelizar el subplan SELECT, la base de datos usa varios procesos de trabajador para recuperar datos. Luego, la base de datos inserta los datos recuperados en la tabla de destino. Esta división del trabajo puede generar mejoras en el rendimiento de la base de datos.
Cómo funcionan los planes de consultas paralelas en PostgreSQL
En PostgreSQL, el optimizador de consultas puede crear un plan paralelo para una consulta completa o parte de ella. Cuando se genera un plan paralelo, se agrega un nodo Gather o Gather Merge en la parte superior del plan.
Este nodo coordina varios procesos de trabajo paralelos. Cada trabajador ejecuta una parte de la tarea, por ejemplo, escanear una porción de una tabla. Luego, el nodo Gather recopila los resultados de todos los trabajadores y los pasa a la siguiente etapa de la consulta o de vuelta al cliente.
Por ejemplo, el siguiente plan de consulta muestra un nodo Gather que planea usar cinco procesos de trabajador para un análisis secuencial paralelo en la tabla t1.
EXPLAIN SELECT * FROM t1;
QUERY PLAN
-------------------------------------------------------------
Gather (cost=0.00..143359.76 rows=9999878 width=60)
Workers Planned: 5
-> Parallel Seq Scan on t1 (cost=0.00..143359.76 rows=1999976 width=60)
(3 rows)
Ejecución paralela para las instrucciones INSERT…SELECT
AlloyDB mejora el rendimiento de INSERT INTO ... SELECT con varios procesos de trabajo para paralelizar la instrucción SELECT.
Esta división del trabajo puede generar mejoras en el rendimiento de la base de datos.
La consulta debe ser segura para el procesamiento paralelo y no debe haber condiciones que impidan la paralelización.
Muchas operaciones de bases de datos usan instrucciones INSERT INTO ... SELECT para agregar filas nuevas a una tabla. A menudo, la parte SELECT de la instrucción es la que requiere más recursos de la consulta.
La funcionalidad se controla con los siguientes parámetros de configuración:
enable_parallel_select_for_insert_select: Habilita o inhabilita la función . Este parámetro está activado de forma predeterminada en PostgreSQL 14 y versiones posteriores.enable_parallel_select_for_insert_select_into_part_table: Habilita o inhabilita la función que te permite insertar datos en tablas particionadas. Este parámetro está desactivado de forma predeterminada en PostgreSQL 16 y versiones posteriores.
Para que el optimizador de consultas considere un plan paralelo, la instrucción INSERT SELECT debe ser segura para el paralelismo. Esto significa que ninguna parte de la operación puede contener funciones o expresiones que no se puedan ejecutar de forma segura en paralelo. Si se determina que alguna parte de la consulta no es segura para la ejecución paralela, el optimizador recurre a un plan no paralelo. Para obtener más información, consulta parallel-safety.
Condiciones que impiden la ejecución paralela
El optimizador de consultas no usa un plan paralelo si la instrucción INSERT SELECT se considera no segura para el procesamiento paralelo. Las siguientes condiciones impiden la paralelización:
- La tabla de destino es una tabla externa.
- La consulta usa una expresión de tabla común (CTE) modificable que contiene una instrucción de modificación de datos, por ejemplo,
DELETE. - Un índice en la tabla de destino usa una expresión o función no segura paralela.
- Una columna de la tabla de destino tiene un valor predeterminado que usa una función paralela no segura.
- Un activador en la tabla de destino usa una expresión o función paralela no segura.
- La tabla de destino tiene una columna DOMAIN con una restricción
CHECKque usa una función paralela no segura. - Una restricción
CHECKen la tabla de destino contiene una expresión o función paralela no segura. - La tabla de destino es una tabla particionada y
enable_parallel_select_for_insert_select_into_part_tableestá inhabilitado.
Antes de comenzar
En este documento, se supone que tienes una base de datos de AlloyDB. Para crear una base de datos, consulta Crea un clúster y su instancia principal y Crea y administra una base de datos.
Roles obligatorios
Para obtener los permisos que necesitas para cambiar las marcas de la base de datos a nivel de la sesión, pídele a tu administrador que te otorgue el rol de Identity and Access Management (IAM) de usuario de la base de datos de AlloyDB (roles/alloydb.databaseUser) en tu proyecto. Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.
Habilita los parámetros de ejecución paralela
Para habilitar la ejecución paralela de tablas de destino particionadas, sigue estos pasos:
En la consola de Google Cloud , ve a la página Clústeres.
Selecciona un clúster de la lista.
En el menú de navegación, haz clic en AlloyDB Studio.
Accede a AlloyDB Studio con el nombre de tu base de datos, tu nombre de usuario y tu contraseña.
Establece el GUC
enable_parallel_select_for_insert_select_into_part_tableenon.SET enable_parallel_select_for_insert_select_into_part_table = on;Después de habilitar el parámetro de configuración de GUC, el optimizador de consultas considera automáticamente los planes paralelos para las instrucciones
INSERT INTO ... SELECTen las que el destino es una tabla particionada, siempre que se determine que la consulta es segura para el procesamiento paralelo.El siguiente ejemplo genera un plan EXPLAIN que muestra un nodo Gather, lo que indica que el
SELECTdesource_tablese ejecuta en paralelo.-- Create a partitioned table CREATE TABLE part_table (a INT, b TEXT) PARTITION BY RANGE (a); CREATE TABLE part_table_1 PARTITION OF part_table FOR VALUES FROM (MINVALUE) TO (1000); CREATE TABLE part_table_2 PARTITION OF part_table FOR VALUES FROM (1000) TO (MAXVALUE); -- Create a source table CREATE TABLE source_table (c1 INT, c2 TEXT); INSERT INTO source_table SELECT i, 'value_' || i FROM generate_series(1, 2000) i; ANALYZE source_table; -- Enable the feature SET enable_parallel_select_for_insert_select_into_part_table = on; -- Optional for parallelizing the query with a small amount of data SET parallel_setup_cost=0; SET parallel_tuple_cost=0; SET min_parallel_table_scan_size=0; -- Run the insert with a parallelizable select EXPLAIN INSERT INTO part_table SELECT * FROM source_table;Esto devuelve el siguiente resultado:
EXPLAIN (COSTS OFF) INSERT INTO part_table SELECT * FROM source_table; QUERY PLAN ----------------------------------------------- Insert on part_table -> Gather Workers Planned: 2 -> Parallel Seq Scan on source_table (4 rows)
Inhabilita los parámetros de ejecución paralela
Para inhabilitar los parámetros, sigue estos pasos:
En la consola de Google Cloud , ve a la página Clústeres.
Selecciona un clúster de la lista.
En el menú de navegación, haz clic en AlloyDB Studio.
Accede a AlloyDB Studio con el nombre de tu base de datos, tu nombre de usuario y tu contraseña.
Para inhabilitar el parámetro
enable_parallel_select_for_insert_select, ejecuta el siguiente comando SQL:SET enable_parallel_select_for_insert_select = OFF;Para inhabilitar el parámetro
enable_parallel_select_for_insert_select_into_part_table, ejecuta el siguiente comando SQL:SET enable_parallel_select_for_insert_select_into_part_table = OFF;
Verifica un plan paralelo
Puedes verificar que el optimizador esté usando un plan paralelo con el comando EXPLAIN. Busca un nodo Gather y los atributos Workers Planned o Workers Launched en el plan de consultas.
Ejemplo de tabla estándar
En el siguiente ejemplo de plan, se inician seis procesos de trabajo para una unión hash paralela para ejecutar la instrucción SELECT.
EXPLAIN (ANALYZE)
INSERT INTO t1 SELECT t2.* FROM t1, t2 WHERE t1.c1 != t2.c1 AND t1.c2 = t2.c2;
QUERY PLAN
------------------------------------------------------------------------------------
Insert on t1 (cost=1209138.00..12801765.49 rows=0 width=0) (actual time=16812.677..19337.150 rows=0 loops=1)
-> Gather (cost=1209138.00..12801765.49 rows=99995407 width=24) (actual time=16812.674..19337.144 rows=0 loops=1)
Workers Planned: 6
Workers Launched: 6
-> Parallel Hash Join (...)
(...)
Ejemplo de tabla particionada
En el siguiente ejemplo, se muestra que, después de habilitar la función para las tablas particionadas, el plan muestra un nodo Gather con cuatro trabajadores planificados para SELECT.
-- First, enable the feature for partitioned tables
SET enable_parallel_select_for_insert_select_into_part_table = ON;
-- Then, explain the query
EXPLAIN (COSTS OFF) INSERT INTO part_table SELECT * FROM source_table;
QUERY PLAN
-----------------------------------------------
Insert on part_table
-> Gather
Workers Planned: 2
-> Parallel Seq Scan on source_table
(4 rows)
¿Qué sigue?
- Obtén más información sobre parallel-safety.