L'utilizzo dell'esecuzione parallela per la parte SELECT di una query INSERT INTO ... SELECT
può migliorare le prestazioni delle query AlloyDB per PostgreSQL, in particolare
per le tabelle partizionate e le query complesse.
Parallelizzando il piano secondario SELECT, il database utilizza più processi worker per recuperare i dati. Il database inserisce quindi i dati recuperati nella tabella di destinazione. Questa divisione del lavoro può portare a miglioramenti delle prestazioni del database.
Come funzionano i piani di query parallele in PostgreSQL
In PostgreSQL, l'ottimizzatore di query può creare un piano parallelo per un'intera query o parte di una query. Quando viene generato un piano parallelo, viene aggiunto un nodo Gather
o Gather Merge nella parte superiore del piano.
Questo nodo coordina più processi worker paralleli. Ogni worker esegue una parte dell'attività, ad esempio la scansione di una porzione di una tabella. Il nodo Gather
raccoglie quindi i risultati di tutti i worker e li trasmette alla fase successiva
della query o di nuovo al client.
Ad esempio, il seguente piano di query mostra un nodo Gather che prevede di utilizzare
cinque processi di lavoro per una scansione sequenziale parallela nella tabella 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)
Esecuzione parallela per le istruzioni INSERT...SELECT
AlloyDB migliora le prestazioni di INSERT INTO ... SELECT utilizzando
più processi di lavoro per parallelizzare l'istruzione SELECT.
Questa divisione del lavoro può portare a miglioramenti delle prestazioni del database.
La query deve essere sicura per l'esecuzione in parallelo e non devono essere presenti condizioni che impediscono
la parallelizzazione.
Molte operazioni di database utilizzano istruzioni INSERT INTO ... SELECT per aggiungere nuove
righe a una tabella. Spesso, la parte SELECT dell'istruzione è la parte della query che richiede più risorse.
La funzionalità è controllata dai seguenti parametri di configurazione:
enable_parallel_select_for_insert_select: attiva o disattiva la funzionalità . Questo parametro è attivo per impostazione predefinita in PostgreSQL 14 e versioni successive.enable_parallel_select_for_insert_select_into_part_table: attiva o disattiva la funzionalità che consente di inserire dati nelle tabelle partizionate. Questo parametro è disattivato per impostazione predefinita in PostgreSQL 16 e versioni successive.
Affinché lo strumento di pianificazione delle query prenda in considerazione un piano parallelo, l'istruzione INSERT SELECT
deve essere sicura per l'esecuzione parallela. Ciò significa che nessuna parte dell'operazione può
contenere funzioni o espressioni che non possono essere eseguite in modo sicuro in parallelo. Se
una parte della query viene considerata non sicura per l'esecuzione parallela, lo strumento di ottimizzazione
torna a un piano non parallelo. Per ulteriori informazioni, consulta
parallel-safety.
Condizioni che impediscono l'esecuzione parallela
L'ottimizzatore delle query non utilizza un piano parallelo se l'istruzione INSERT SELECT
è considerata non sicura per l'esecuzione parallela. Le seguenti condizioni impediscono
la parallelizzazione:
- La tabella di destinazione è una tabella esterna.
- La query utilizza un'espressione di tabella comune (CTE) modificabile che contiene
un'istruzione di modifica dei dati, ad esempio
DELETE. - Un indice nella tabella di destinazione utilizza un'espressione o una funzione non sicura per il parallelismo.
- Una colonna della tabella di destinazione ha un valore predefinito che utilizza una funzione non sicura parallela.
- Un trigger nella tabella di destinazione utilizza un'espressione o una funzione non sicura per il parallelismo.
- La tabella di destinazione ha una colonna DOMAIN con un vincolo
CHECKche utilizza una funzione parallela non sicura. - Un vincolo
CHECKnella tabella di destinazione contiene un'espressione o una funzione non sicura per l'elaborazione parallela. - La tabella di destinazione è una tabella partizionata e
enable_parallel_select_for_insert_select_into_part_tableè disattivato.
Prima di iniziare
Questo documento presuppone che tu disponga di un database AlloyDB. Per creare un database, consulta Creare un cluster e la relativa istanza principale e Creare e gestire un database.
Ruoli obbligatori
Per ottenere le autorizzazioni necessarie per modificare i flag di database a livello di sessione, chiedi all'amministratore di concederti il ruolo IAM Utente database AlloyDB (roles/alloydb.databaseUser) sul tuo progetto. Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.
Attiva i parametri di esecuzione parallela
Per attivare l'esecuzione parallela per le tabelle di destinazione partizionate:
Nella console Google Cloud , vai alla pagina Cluster.
Seleziona un cluster dall'elenco.
Nel menu di navigazione, fai clic su AlloyDB Studio.
Accedi ad AlloyDB Studio utilizzando il nome del database, il nome utente e la password.
Imposta il GUC
enable_parallel_select_for_insert_select_into_part_tablesuon.SET enable_parallel_select_for_insert_select_into_part_table = on;Dopo aver attivato il parametro GUC, il pianificatore di query prende automaticamente in considerazione i piani paralleli per le istruzioni
INSERT INTO ... SELECTin cui la destinazione è una tabella partizionata, a condizione che la query sia considerata sicura per l'esecuzione parallela.Il seguente esempio genera un piano EXPLAIN che mostra un nodo Gather, il quale indica che l'
SELECTdisource_tableviene eseguita in parallelo.-- 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;Viene restituito il seguente output:
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)
Disattiva i parametri di esecuzione parallela
Per disattivare i parametri:
Nella console Google Cloud , vai alla pagina Cluster.
Seleziona un cluster dall'elenco.
Nel menu di navigazione, fai clic su AlloyDB Studio.
Accedi ad AlloyDB Studio utilizzando il nome del database, il nome utente e la password.
Per disattivare il parametro
enable_parallel_select_for_insert_select, esegui il seguente comando SQL:SET enable_parallel_select_for_insert_select = OFF;Per disattivare il parametro
enable_parallel_select_for_insert_select_into_part_table, esegui il seguente comando SQL:SET enable_parallel_select_for_insert_select_into_part_table = OFF;
Verificare un piano parallelo
Puoi verificare che l'ottimizzatore stia utilizzando un piano parallelo utilizzando il comando
EXPLAIN. Cerca un nodo Gather e gli attributi Workers Planned o
Workers Launched nel piano di query.
Esempio di tabella standard
Nell'esempio di piano seguente, vengono avviati sei processi di lavoro per un hash join parallelo per eseguire l'istruzione 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 (...)
(...)
Esempio di tabella partizionata
L'esempio seguente mostra che, dopo aver attivato la funzionalità per le tabelle partizionate, il piano mostra un nodo Gather con quattro worker pianificati per 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)
Passaggi successivi
- Scopri di più su parallel-safety.