Parallell aggregering och hash-joiner
Utnyttja partiella aggregat och parallellmedvetna joiner för tunga grupperingsarbetsbelastningar.
Parallell aggregering och hash-joiner är en gratis lektion i Prestandaoptimering och frågeoptimering i PostgreSQL på CoddyKit. Detta är lektion 3 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Prestandaoptimering och frågeoptimering i PostgreSQL, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Prestandaoptimering och frågeoptimering i PostgreSQL innehåller totalt 4 lektioner.
Varför parallellism för aggregering
Tunga grupperingsfrågor som GROUP BY över hundratals miljoner rader är vanligtvis CPU-bundna: det mesta av tiden går åt till att beräkna hashvärden för nycklar och kombinera värden, inte till att vänta på I/O.
En enda backend-process kan bara mätta en kärna. PostgreSQLs mekanism för parallella frågor låter planeraren dela upp skanningen och aggregeringen på flera parallella arbetare, som var och en kör på sin egen kärna, och sedan kombinera resultaten.
- Backend-processen som startar körningen är ledaren.
- De extra processerna är parallella arbetare.
- Arbetet delas upp på tabellskanningsnivå och slås samman högst upp.
Den här lektionen fokuserar på två delar som samarbetar: parallell aggregering (partiella aggregat) och hash-joiner med parallellitetsstöd.
Partiellt och slutligt aggregat
Parallell aggregering fungerar genom att varje aggregering delas upp i två faser:
- Partial Aggregate — varje workerprocess aggregerar sitt eget utsnitt av rader till ett delresultat (till exempel en löpande summa och ett antal).
- Finalize Aggregate — ledarprocessen kombinerar delresultaten till det slutliga resultatet.
Detta är möjligt eftersom aggregeringar som count, sum, avg, min och max är kombinerbara: ett delresultat från en workerprocess kan slås ihop med ett annat via en kombinationsfunktion.
I planerna visas detta som en Partial Aggregate-nod under Gather och en Finalize Aggregate-nod ovanför den.
Läsa en plan för parallell aggregering
Kör EXPLAIN på en stor grupperad fråga och leta efter sandwichstrukturen Finalize / Gather / Partial. Noden Gather är där resultaten från workerprocesserna går tillbaka till ledarprocessen.
Observera Workers Planned: den parallellism som planeraren har avsett. Vid körning rapporterar EXPLAIN ANALYZE även Workers Launched, vilket kan vara lägre om systemet har slut på workerplatser.
EXPLAIN (COSTS OFF)
SELECT customer_id, sum(amount) AS total
FROM orders
GROUP BY customer_id;
-- Finalize HashAggregate
-- Group Key: customer_id
-- -> Gather
-- Workers Planned: 4
-- -> Partial HashAggregate
-- Group Key: customer_id
-- -> Parallel Seq Scan on ordersInställningar som styr parallellism
Planeraren överväger bara parallella planer när vissa GUC:er tillåter det och när tabellen är tillräckligt stor för att det ska löna sig.
max_parallel_workers_per_gather— maximalt antal workerprocesser som en enskildGatherfår använda (0 inaktiverar parallella frågor för den noden).max_parallel_workers— gräns för hela instansen.max_worker_processes— en hård gräns på operativsystemnivå för alla bakgrundsworkerprocesser.min_parallel_table_scan_size(standardvärde 8MB) — tabellen måste vara större än detta för att en parallell genomsökning ska övervägas.parallel_setup_costochparallel_tuple_cost— modellerar kostnaden för att starta workerprocesser och skicka tupler.
SET max_parallel_workers_per_gather = 4;
SET max_parallel_workers = 8;
SHOW min_parallel_table_scan_size; -- 8MB default
SHOW parallel_setup_cost; -- 1000 defaultTvinga fram parallellism för experiment
På små testtabeller kan planeraren bedöma att parallellismens startkostnad inte lönar sig. För att studera planer kan du kraftigt styra planeraren mot parallellism och sedan mäta på realistiska data.
Om du sätter parallel_setup_cost och parallel_tuple_cost till 0 ignorerar planeraren startkostnaden för workerprocesser, så att den väljer parallella planer även för måttligt stora indata. Detta är ett diagnostiskt knep, inte en inställning för produktion.
SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0;
SET min_parallel_table_scan_size = '0';
SET max_parallel_workers_per_gather = 4;
EXPLAIN (ANALYZE, COSTS OFF)
SELECT region, count(*)
FROM sales
GROUP BY region;Parallellmedveten hash-join
En Hash Join bygger en hash-tabell i minnet från den mindre sidan (byggsidan) och slår sedan upp rader från den större sidan i den. I en Parallel Hash Join är själva join-operationen parallellmedveten.
- Plannoden är
Parallel Hash Joinmed en inre nod av typenParallel Hash. - Alla workerprocesser samarbetar för att bygga en gemensam hash-tabell i dynamiskt delat minne.
- Därefter slår varje workerprocess upp sin del av den yttre relationen i den gemensamma tabellen.
Detta gör att varje workerprocess slipper bygga en egen privat kopia av hash-tabellen, vilket sparar både CPU och minne.
EXPLAIN (COSTS OFF)
SELECT o.customer_id, sum(o.amount)
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE c.country = 'DE'
GROUP BY o.customer_id;
-- Finalize GroupAggregate
-- -> Gather
-- -> Partial HashAggregate
-- -> Parallel Hash Join
-- Hash Cond: (o.customer_id = c.id)
-- -> Parallel Seq Scan on orders o
-- -> Parallel Hash
-- -> Parallel Seq Scan on customers cGemensam hash jämfört med hash per worker
Var noga med att skilja mellan två planer som ytligt sett liknar varandra:
- Parallel Hash Join (med
Parallel Hash): workerprocesserna bygger tillsammans en gemensam hash-tabell. Byggkostnaden och minnet delas. - Hash Join under Gather (vanlig
Hash): varje workerprocess bygger sin egen fullständiga kopia av hash-tabellen. Byggarbetet och minnesåtgången multipliceras med antalet workerprocesser.
För en stor byggsida är den parallellmedvetna varianten mycket billigare. Planeraren väljer den när båda sidorna kan genomsökas parallellt och joinen är parallellsäker.
work_mem och hash-tabellen
Hash-joiner och hash-aggregeringar ryms inom work_mem. Om hash-tabellen inte får plats spiller PostgreSQL över till disk i batchar, vilket är mycket långsammare.
I EXPLAIN (ANALYZE, BUFFERS) ska du leta efter Batches: N där N > 1 och Disk Usage på hash-noder — tecken på att work_mem är för litet för byggsidan.
För Parallel Hash kan den gemensamma tabellen använda en större effektiv budget: workerprocessernas tilldelningar av work_mem slås ihop för den gemensamma hash-tabellen, vilket är ytterligare en anledning till att den parallellmedvetna joinen skalar bra.
SET work_mem = '256MB';
EXPLAIN (ANALYZE, BUFFERS, COSTS OFF)
SELECT o.product_id, count(*)
FROM orders o
JOIN products p ON p.id = o.product_id
GROUP BY o.product_id;
-- Look for: Parallel Hash Batches: 1 Memory Usage: ...kBVad som inaktiverar parallellism
Planeraren avvisar parallella planer när frågan innehåller parallellosäkra element. Vanliga hinder är:
- Anrop av en funktion som är märkt
PARALLEL UNSAFE(standard för användardefinierade funktioner om du inte märker dem). - Skrivning av data: mål för
INSERT,UPDATEochDELETE(den ändrande delen körs seriellt). - Markörer / radlåsning med
FOR UPDATEi många fall. max_parallel_workers_per_gather = 0.
Märk rena funktioner utan sidoeffekter som PARALLEL SAFE så att de inte blockerar parallella planer.
CREATE FUNCTION norm_region(txt text)
RETURNS text
LANGUAGE sql
IMMUTABLE
PARALLEL SAFE
AS $fn$ SELECT lower(trim(txt)) $fn$;Ledarprocessens deltagande
Som standard utför ledarprocessen två uppgifter: den samlar både indata från workerprocesserna och hjälper till att köra den parallella planen. Detta styrs av parallel_leader_participation (standardvärde on).
För en fråga med N planerade workerprocesser är den effektiva parallellismen ungefär N+1 när ledarprocessen deltar. Men om ledarprocessen blir en flaskhals när den samlar in ett stort flöde av tupler kan det ibland hjälpa att stänga av deltagandet med off, så att workerprocesserna kan köra utan hinder — mät på båda sätten.
SET parallel_leader_participation = off;
EXPLAIN (ANALYZE, COSTS OFF)
SELECT category_id, avg(price)
FROM products
GROUP BY category_id;Justera en tung grupperingsbelastning
Så här kan du gå tillväga för en CPU-bunden grupperad join:
- Höj
max_parallel_workers_per_gatherså att planeraren kan dela upp genomsökningen (börja med antalet lediga kärnor). - Se till att
max_parallel_workersochmax_worker_processesär tillräckligt höga för att workerprocesserna faktiskt ska startas och inte begränsas. - Höj
work_memtills hash-noderna visarBatches: 1(ingen spillning). - Kontrollera att planen visar
Parallel Hash Join+Partial/Finalize Aggregateoch attWorkers Launchedär lika medWorkers Planned.
Verifiera alltid med EXPLAIN (ANALYZE, BUFFERS) på data i produktionsstorlek — kostnader i liten skala kan vara missvisande.
SET max_parallel_workers_per_gather = 6;
SET work_mem = '512MB';
EXPLAIN (ANALYZE, BUFFERS, COSTS OFF)
SELECT c.region, count(*) AS n, sum(o.amount) AS revenue
FROM orders o
JOIN customers c ON c.id = o.customer_id
GROUP BY c.region;Snabbkontroll
Testa din förståelse av parallellmedvetna joiner.
Sammanfattning
Du har lärt dig hur PostgreSQL snabbar upp CPU-bundna grupperingsarbetsbelastningar:
- Parallell aggregering delar upp arbetet i
Partial Aggregateper workerprocess ochFinalize Aggregatehos ledarprocessen, vilket är möjligt eftersom aggregeringar kan kombineras. - Parallel Hash Join bygger en gemensam hash-tabell över flera workerprocesser och undviker duplicering av byggkostnad och minne för varje workerprocess.
- Sandwichstrukturen
Finalize / Gather / Partialoch noder av typenParallel Hashvisar hur du känner igen dessa planer iEXPLAIN. - Styr parallellismen med
max_parallel_workers_per_gather,max_parallel_workersoch trösklar för tabellstorlek; dimensionera hash-tabeller medwork_memför att undvika spillning till disk. - Parallellosäkra funktioner och satser som ändrar data inaktiverar parallella planer; märk rena funktioner som
PARALLEL SAFE.
Kontrollera alltid att Workers Launched överensstämmer med Workers Planned och verifiera med EXPLAIN (ANALYZE, BUFFERS) på verkliga data.
Lär dig SQL med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 22
- Lektioner
- 88
Vanliga frågor
Är lektionen ”Parallell aggregering och hash-joiner” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Prestandaoptimering och frågeoptimering i PostgreSQL, inklusive ”Parallell aggregering och hash-joiner”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Prestandaoptimering och frågeoptimering i PostgreSQL innehåller totalt 4 lektioner.
Vad lär jag mig i ”Parallell aggregering och hash-joiner”?
Utnyttja partiella aggregat och parallellmedvetna joiner för tunga grupperingsarbetsbelastningar. Ni övar på Prestandaoptimering och frågeoptimering i PostgreSQL med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Prestandaoptimering och frågeoptimering i PostgreSQL?
Du behöver inga förkunskaper. Utbildningen i Prestandaoptimering och frågeoptimering i PostgreSQL på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.
Hur lång tid tar lektionen ”Parallell aggregering och hash-joiner”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Prestandaoptimering och frågeoptimering i PostgreSQL-lektionen?
Ja. Varje Prestandaoptimering och frågeoptimering i PostgreSQL-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- När planeraren väljer parallella planer
- Finjustera arbetarantal och Gather-kostnader
- Parallell aggregering och hash-joiner
- Diagnostisera varför parallellism inaktiverades