Ydelsesoptimering og optimering af forespørgsler i PostgreSQL · Lektion

Hvornår planner’en vælger parallelle planer

Forstå de omkostningstærskler og tabelstørrelser, der udløser parallelle scans og joins.

Lektion 1 af 413 trin

Hvornår planner’en vælger parallelle planer er en gratis Ydelsesoptimering og optimering af forespørgsler i PostgreSQL-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Ydelsesoptimering og optimering af forespørgsler i PostgreSQL, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Ydelsesoptimering og optimering af forespørgsler i PostgreSQL-kurset indeholder 4 lektioner i alt.

Parallelisme er en omkostningsbeslutning

PostgreSQL kører ikke alle forespørgsler parallelt. Planlæggeren genererer kun en parallel plan, når den vurderer, at den ekstra omkostning ved at starte arbejdere opvejes af en hurtigere kørsel.

  • Arbejdere koster: Planlæggeren tilføjer opstarts- og omkostninger ved overførsel af tupler for hver arbejder.
  • Parallelisme kan kun betale sig, når tabellen er stor nok, og arbejdet er CPU- eller I/O-tungt nok.
  • Små tabeller og billige forespørgsler forbliver sekventielle — omkostningen ville dominere.

I denne lektion lærer du præcis, hvilke tærskler og tabelstørrelser der får planlæggeren til at vælge en parallel plan.

De tre styrende GUC'er

Tre indstillinger afgør, om parallelisme overhovedet overvejes, før nogen omkostningsberegning udføres:

  • max_parallel_workers_per_gather — det maksimale antal arbejdere, som en enkelt Gather-node må anmode om (standard 2). Hvis værdien er 0, er parallelisme deaktiveret for den forespørgsel.
  • max_parallel_workers — grænsen for hele instansen (standard 8).
  • max_worker_processes — den hårde OS-grænse for baggrundsarbejdere (standard 8).

Hvis max_parallel_workers_per_gather = 0, producerer planlæggeren aldrig en parallel sti, uanset tabelstørrelsen.

SHOW max_parallel_workers_per_gather;
SHOW max_parallel_workers;
SHOW max_worker_processes;

Størrelsestærsklen: min_parallel_table_scan_size

Den vigtigste udløser for tabelstørrelse er min_parallel_table_scan_size (standard 8MB). En relation skal mindst have denne størrelse, før planlæggeren overhovedet overvejer en parallel sekventiel scanning af den.

  • For indekser er den tilsvarende indstilling min_parallel_index_scan_size (standard 512kB).
  • Under tærsklen behandles relationen som for lille til, at parallelisme kan betale sig.

En tabel på 6 MB får derfor næsten aldrig en parallel scanning, mens en tabel på 1 GB nemt overskrider grænsen.

SHOW min_parallel_table_scan_size;
SHOW min_parallel_index_scan_size;

Sådan skalerer antallet af arbejdere med størrelsen

Antallet af arbejdere er ikke fast — det vokser logaritmisk med tabelstørrelsen. Hver gang relationen bliver tre gange større end tærsklen, tillader planlæggeren én ekstra arbejder (begrænset af max_parallel_workers_per_gather).

  • 8 MB til 24 MB: op til 1 arbejder
  • 24 MB til 72 MB: op til 2 arbejdere
  • 72 MB til 216 MB: op til 3 arbejdere
  • Hvert trin ganger den foregående grænse med 3.

Derfor ændrer en fordobling af en lille tabel sjældent antallet af arbejdere, mens en ændring fra 10 MB til 1 GB gør det.

Omkostninger pr. tupel og til opsætning

Når en parallel sti er mulig, vejer planlæggeren to omkostningsstraffe op mod den sekventielle plan:

  • parallel_setup_cost (standard 1000) — en engangsudgift til at starte arbejdere og nedlægge den delte hukommelse. Den er stor, og derfor forbliver små forespørgsler sekventielle.
  • parallel_tuple_cost (standard 0.1) — opkræves for hver tupel, der sendes fra en arbejder gennem Gather-noden til lederen.

En parallel plan vinder kun, når den dividerede scanningsomkostning pr. arbejder minus disse straffe er lavere end den sekventielle omkostning.

SHOW parallel_setup_cost;
SHOW parallel_tuple_cost;

Læsning af en parallel plan i EXPLAIN

Du bekræfter en parallel plan ved at lede efter en Gather- eller Gather Merge-node og scanningsnoder med præfikset Parallel under den.

  • Gather samler rækker fra arbejdere; Workers Planned viser, hvor mange der blev anmodet om.
  • Noder under Gather (f.eks. Parallel Seq Scan) kører én gang pr. arbejder plus lederen.
  • Antal rækker under Gather er estimater pr. arbejder, ikke totalen.
EXPLAIN (ANALYZE, VERBOSE)
SELECT count(*)
FROM orders
WHERE amount > 100;

Tving parallelisme til test

Hvis du vil se en parallel plan på en mindre tabel under test, kan du sænke de styrende tærskler på sessionsniveau. Det ændrer ikke dataene — kun planlæggerens villighed til at parallelisere.

  • Sæt min_parallel_table_scan_size = 0 for at fjerne størrelsesbegrænsningen.
  • Sæt parallel_setup_cost = 0 og parallel_tuple_cost = 0 for at fjerne omkostningsstraffene.
  • Sæt force_parallel_mode = on (omdøbt til debug_parallel_query i PG16+) for at tvinge en parallel sti, hvor der findes en.

Dette er diagnosticeringsindstillinger — lad dem aldrig være slået til i produktion.

SET min_parallel_table_scan_size = 0;
SET parallel_setup_cost = 0;
SET parallel_tuple_cost = 0;
SET max_parallel_workers_per_gather = 4;

Parallelbevidst over for parallelbegrænset

Ikke alle operationer kan køre i en parallel arbejder. Planlæggeren klassificerer dele af forespørgslen:

  • Parallel-safe — kan køre i en arbejder (de fleste immutable/stable-funktioner og almindelige scanninger).
  • Parallel-restricted — skal kun køre i lederen (f.eks. referencer til midlertidige tabeller, korrelerede underplaner og nogle CTE'er).
  • Parallel-unsafe — deaktiverer parallelisme for hele forespørgslen (f.eks. funktioner markeret med PARALLEL UNSAFE, skrivende CTE'er og sekvenskald).

Én VOLATILE- eller PARALLEL UNSAFE-funktion i forespørgslen kan undertrykke en ellers parallel plan.

CREATE FUNCTION score(x int) RETURNS int
LANGUAGE sql IMMUTABLE PARALLEL SAFE
AS 'SELECT x * 2';

Parallelle joins og aggregater

Parallelisme er ikke begrænset til scanninger. Når en drivende relation scannes parallelt, kan planlæggeren sende joins og aggregering ind i arbejderne:

  • Parallel Hash Join — arbejderne opbygger i fællesskab én delt hashtabel.
  • Parallel Nested Loop / Merge Join — hver arbejder joiner sit udsnit af den ydre relation.
  • Partial Aggregate — hver arbejder aggregerer sine rækker, hvorefter et Finalize Aggregate over Gather kombinerer delresultaterne.

Derfor er en stor GROUP BY over en stor faktatabel en klassisk kandidat til en parallel plan.

EXPLAIN
SELECT customer_id, count(*)
FROM orders
GROUP BY customer_id;

Ting, der ubemærket deaktiverer parallelisme

Selv på en enorm tabel kan flere forhold helt blokere en parallel plan:

  • Forespørgslen køres inde i en cursor/FETCH eller med række-låsning via SELECT ... FOR UPDATE.
  • Det er en datamodificerende sætning i PG-versioner før 11 (senere versioner tillader parallel INSERT ... SELECT / indeksopbygning, men ikke parallel udførelse af UPDATE/DELETE).
  • Den kalder en PARALLEL UNSAFE-funktion eller kører inde i en funktion, der allerede har gjort krav på alle workers.
  • max_parallel_workers_per_gather = 0 for sessionen.

Når en plan, som du forventer er parallel, ikke er det, skal du kontrollere disse forhold, før du justerer omkostningerne.

Samling af tærsklerne

For at planner'en vælger en parallel plan, skal alle disse betingelser være opfyldt:

  • Relationsstørrelsen skal mindst være min_parallel_table_scan_size (8 MB) for scanninger eller over indeksstørrelsestærsklen.
  • max_parallel_workers_per_gather > 0, og der skal være et tilgængeligt worker-budget på instansniveau.
  • Forespørgslen må kun indeholde parallel-sikre (eller højst parallel-begrænsede) elementer.
  • De estimerede parallelle omkostninger efter parallel_setup_cost og parallel_tuple_cost skal være lavere end den bedste sekventielle plan.

Hvis bare én betingelse ikke er opfyldt, får du en sekventiel plan — som regel af en god grund.

EXPLAIN (ANALYZE, BUFFERS)
SELECT sum(amount)
FROM orders
WHERE created_at >= DATE '2024-01-01';

Hurtigt tjek

Test din forståelse af, hvad der udløser parallelle planer.

Opsummering

De vigtigste pointer om, hvornår PostgreSQL vælger en parallel plan:

  • Parallel udførelse er en omkostningsbeslutning, der først begrænses af størrelsen og derefter af omkostningsberegningen.
  • min_parallel_table_scan_size (8 MB) er den primære udløser for tabelstørrelse; min_parallel_index_scan_size (512 kB) dækker indekser.
  • Antallet af workers vokser logaritmisk — én ekstra worker, hver gang størrelsen tredobles — og begrænses af max_parallel_workers_per_gather.
  • parallel_setup_cost (1000) og parallel_tuple_cost (0,1) skal opvejes af hastighedsforøgelsen pr. worker.
  • Parallel-usikre funktioner, række-låsning og en indstilling med nul workers kan deaktivere parallel udførelse, selv på enorme tabeller.
  • Bekræft planer ved at se efter noderne Gather / Partial Aggregate i EXPLAIN.
Gratis at komme i gang

Lær SQL med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
22
Lektioner
88

Ofte stillede spørgsmål

Er lektionen “Hvornår planner’en vælger parallelle planer” gratis?

Ja — alle 3 lektioner i læringssporet Ydelsesoptimering og optimering af forespørgsler i PostgreSQL, inklusive “Hvornår planner’en vælger parallelle planer”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Ydelsesoptimering og optimering af forespørgsler i PostgreSQL-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Hvornår planner’en vælger parallelle planer”?

Forstå de omkostningstærskler og tabelstørrelser, der udløser parallelle scans og joins. Du øver dig i Ydelsesoptimering og optimering af forespørgsler i PostgreSQL med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Ydelsesoptimering og optimering af forespørgsler i PostgreSQL?

Der kræves ingen tidligere erfaring. Ydelsesoptimering og optimering af forespørgsler i PostgreSQL på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Hvornår planner’en vælger parallelle planer”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Ydelsesoptimering og optimering af forespørgsler i PostgreSQL-lektion?

Ja. Alle Ydelsesoptimering og optimering af forespørgsler i PostgreSQL-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Hvornår planner’en vælger parallelle planer
  2. Justering af worker-antal og gather-omkostninger
  3. Parallel aggregering og hash joins
  4. Diagnosticering af, hvorfor parallelisme blev deaktiveret
← Tilbage til Ydelsesoptimering og optimering af forespørgsler i PostgreSQL