Ytelse og spørringsoptimalisering i PostgreSQL · leksjon

Partisjonsbeskjæring ved planlegging og kjøring

Les EXPLAIN-utdata for å bekrefte at statisk og dynamisk partisjonsbeskjæring fjerner irrelevante partisjoner fra spørringene.

Leksjon 2 av 413 trinn

Partisjonsbeskjæring ved planlegging og kjøring er en gratis leksjon i Ytelse og spørringsoptimalisering i PostgreSQL på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Ytelse og spørringsoptimalisering i PostgreSQL, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Ytelse og spørringsoptimalisering i PostgreSQL inneholder totalt 4 leksjoner.

Hvorfor partisjonsbeskjæring er viktig

De partisjonerte en stor tabell slik at PostgreSQL kan hoppe over partisjoner som ikke kan inneholde samsvarende rader. Denne hoppingen kalles partisjonsbeskjæring.

Uten beskjæring kunne en forespørsel som bare berører én måneds data, likevel skanne alle partisjonene for hver måned. Hele ytelsesgevinsten ved partisjonering avhenger av at planleggeren (og noen ganger utføreren) gjenkjenner hvilke partisjoner som er relevante.

  • Beskjæring ved planlegging skjer når planleggeren allerede kjenner filterverdiene.
  • Beskjæring under kjøring skjer når verdiene først blir kjent mens forespørselen kjører.

I denne leksjonen lærer De å bekrefte begge typene ved å lese resultatet fra EXPLAIN.

Eksempeltabellen vår

Gjennom hele leksjonen bruker vi tabellen events, som er områdepartisjonert etter måned på created_at. Hver underpartisjon inneholder radene for én måned.

Dette er den klassiske tidsserieoppsettet der beskjæring gir størst gevinst: Forespørsler gjelder vanligvis et smalt datoområde, så de fleste partisjonene bør hoppes over fullstendig.

CREATE TABLE events (
    id          bigint        NOT NULL,
    created_at  timestamptz   NOT NULL,
    user_id     bigint        NOT NULL,
    payload     jsonb
) PARTITION BY RANGE (created_at);

CREATE TABLE events_2024_01 PARTITION OF events
    FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
CREATE TABLE events_2024_02 PARTITION OF events
    FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
CREATE TABLE events_2024_03 PARTITION OF events
    FOR VALUES FROM ('2024-03-01') TO ('2024-04-01');

Statisk beskjæring ved planlegging

Når filteret sammenligner partisjonsnøkkelen med en konstant, kan planleggeren avgjøre hvilke partisjoner som skal berøres før kjøringen starter. Dette er statisk beskjæring (beskjæring ved planlegging).

Kjør EXPLAIN på en forespørsel som er begrenset til én måned. Planen bør bare referere til den eller de samsvarende partisjonene; de andre vises aldri.

Innstillingen enable_partition_pruning (på som standard) styrer denne virkemåten.

EXPLAIN
SELECT count(*)
FROM events
WHERE created_at >= '2024-02-10'
  AND created_at <  '2024-02-20';

Slik leser De den beskårne planen

Slik ser planen for forespørselen som gjelder én måned, ut. Legg merke til at bare events_2024_02 skannes. events_2024_01 og events_2024_03 mangler fullstendig i planen.

  • Append (eller Seq Scan med ett barn) viser bare partisjonene som er igjen.
  • Beskårne partisjoner etterlater ingen spor i planresultatet.

Dette er den tydeligste bekreftelsen på statisk beskjæring: Tell partisjonene i planen og sammenlign med hvor mange som finnes.

Aggregate
  ->  Seq Scan on events_2024_02 events
        Filter: ((created_at >= '2024-02-10'::timestamptz)
             AND (created_at <  '2024-02-20'::timestamptz))

Når planen fortsatt viser alle partisjonene

Hvis EXPLAIN viser en Append over alle partisjonene, ble statisk beskjæring ikke brukt. Vanlige årsaker er:

  • Filteret refererer ikke til partisjonsnøkkelen (for eksempel filtrerer det bare på user_id).
  • En funksjon omslutter nøkkelen, for eksempel date(created_at) = '2024-02-10', slik at sammenhengen skjules for planleggeren.
  • Verdien er ikke en konstant ved planlegging (parameter eller sammenføyningskolonne) — dette krever beskjæring under kjøring.

La partisjonsnøkkelen stå ubehandlet på én side av sammenligningen, slik at planleggeren kan koble den til partisjonsgrensene.

-- This DEFEATS static pruning: function wraps the key
EXPLAIN SELECT count(*) FROM events
WHERE date(created_at) = '2024-02-15';

-- This ENABLES it: bare key compared to constants
EXPLAIN SELECT count(*) FROM events
WHERE created_at >= '2024-02-15'
  AND created_at <  '2024-02-16';

Hvorfor parametere krever en annen tilnærming

Med en forberedt setning eller en verdi som oppgis ved kjøring kjenner planleggeren kanskje ikke konstanten når den bygger planen. En generisk plan må være gyldig for alle parameterverdier, så den kan ikke beskjære statisk.

I stedet utsetter PostgreSQL avgjørelsen: Den beholder alle partisjonene i planen, men legger til muligheten til å hoppe over dem mens forespørselen kjører. Dette er beskjæring under kjøring.

PREPARE month_count(timestamptz, timestamptz) AS
  SELECT count(*) FROM events
  WHERE created_at >= $1 AND created_at < $2;

EXPLAIN EXECUTE month_count('2024-03-01', '2024-04-01');

Slik finner De beskjæring under kjøring i planen

Beskjæring under kjøring viser seg i EXPLAIN med to viktige markører under en Append-node:

  • Subplans Removed: N — partisjoner som ble forkastet før skanning.
  • For parametriserte planer vises en linje som Filter eller initplan-parametere som styrer beskjæringen.

Hvis De ser Subplans Removed, har utføreren beskåret partisjoner under kjøringen. Hvis De verken ser dette eller en redusert partisjonsliste, fant ingen beskjæring sted.

Aggregate
  ->  Append
        Subplans Removed: 2
        ->  Seq Scan on events_2024_03 events_1
              Filter: ((created_at >= $1) AND (created_at < $2))

Beskjæring under kjøring fra nøstede løkker

Beskjæring under kjøring gjelder ikke bare parametere. Den aktiveres også når partisjonsnøkkelen sammenlignes med en verdi som produseres av den ytre siden av en sammenføyning (en Nested Loop), eller av en underforespørsel.

Hver ytre rad leverer en nøkkelverdi, og for hver av dem reduserer utføreren søket til den relevante partisjonen. Dette er svært verdifullt for selektive oppslag mot en partisjonert faktatabell.

EXPLAIN (ANALYZE, COSTS OFF)
SELECT e.*
FROM date_filter df
JOIN events e
  ON e.created_at >= df.start_ts
 AND e.created_at <  df.end_ts;

Bruk EXPLAIN ANALYZE for å bekrefte at det faktisk ble kjørt

Vanlig EXPLAIN viser hva som kan beskjæres. Bruk EXPLAIN ANALYZE for å bevise at beskjæring faktisk skjedde under en reell kjøring — særlig ved beskjæring under kjøring.

  • Subplans Removed: N vises med det faktiske antallet som ble fjernet under kjøringen.
  • Partisjonene som blir igjen, viser actual rows; beskårne partisjoner viser (never executed) hvis de fortsatt finnes som undernoder.

Ved å lese actual time og actual rows for hver partisjon ser De nøyaktig hvilke underpartisjoner som utførte arbeid.

EXPLAIN (ANALYZE, BUFFERS)
EXECUTE month_count('2024-03-01', '2024-04-01');

Beskjæring er ikke det samme som begrensningsutelukkelse

Eldre versjoner av PostgreSQL brukte constraint_exclusion for partisjonering basert på arv. Moderne deklarativ partisjonering bruker partisjonsbeskjæring, som er raskere og støtter beskjæring under kjøring.

  • enable_partition_pruning = on styrer den nye mekanismen (ved planlegging og under kjøring).
  • constraint_exclusion fungerte bare ved planlegging, og bare med CHECK-begrensninger.

For deklarative partisjoner bør De la enable_partition_pruning stå på og ikke være avhengig av constraint_exclusion.

SHOW enable_partition_pruning;   -- expect: on
SHOW constraint_exclusion;        -- 'partition' (legacy default)

En praktisk sjekkliste

Når du verifiserer pruning for en faktisk spørring, går du gjennom denne listen:

  • Finnes partisjonsnøkkelen i predikatet, uten innpakking og SARGable? Ingen omsluttende funksjoner eller implisitte castinger som hindrer samsvar.
  • Statisk tilfelle: kjør EXPLAIN — forsvinner partisjoner som er beskåret, fra planen?
  • Kjøretidstilfelle: se etter Subplans Removed: N under Append.
  • Bekreft med EXPLAIN ANALYZE at bare de forventede partisjonene faktisk ble brukt.
  • Kontroller innstillingen hvis ingenting beskjæres: enable_partition_pruning må være aktivert.

Hurtigsjekk

En forberedt setning filtrerer en tabell partisjonert etter intervaller på partisjonsnøkkelen ved hjelp av en bundet parameter. De kjører EXPLAIN ANALYZE EXECUTE og vil bekrefte at pruning fant sted.

Oppsummering

De kan nå bekrefte partition pruning fra resultatet av EXPLAIN:

  • Statisk pruning skjer under planleggingen når partisjonsnøkkelen sammenlignes med konstanter; partisjoner som beskjæres, forsvinner ganske enkelt fra planen.
  • Pruning under kjøring håndterer parametere og verdier fra joiner; se etter Subplans Removed: N under Append.
  • Hold partisjonsnøkkelen uten innpakking og SARGable — hvis den omsluttes av en funksjon, hindres pruning.
  • Bruk EXPLAIN ANALYZE for å dokumentere hvilke partisjoner som faktisk ble brukt, og kontroller at enable_partition_pruning er aktivert når ingenting beskjæres.

Når de leser disse markørene, blir partisjonering mer enn et håpefullt designvalg – det blir en verifisert ytelsesgevinst.

Gratis å komme i gang

Lær deg SQL med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
22
Leksjoner
88

Ofte stilte spørsmål

Er leksjonen «Partisjonsbeskjæring ved planlegging og kjøring» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Ytelse og spørringsoptimalisering i PostgreSQL, inkludert «Partisjonsbeskjæring ved planlegging og kjøring», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Ytelse og spørringsoptimalisering i PostgreSQL inneholder totalt 4 leksjoner.

Hva lærer jeg i «Partisjonsbeskjæring ved planlegging og kjøring»?

Les EXPLAIN-utdata for å bekrefte at statisk og dynamisk partisjonsbeskjæring fjerner irrelevante partisjoner fra spørringene. Du øver på Ytelse og spørringsoptimalisering i PostgreSQL med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Ytelse og spørringsoptimalisering i PostgreSQL?

Ingen tidligere erfaring er nødvendig. Ytelse og spørringsoptimalisering i PostgreSQL på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Partisjonsbeskjæring ved planlegging og kjøring»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Ytelse og spørringsoptimalisering i PostgreSQL-leksjonen?

Ja. Alle Ytelse og spørringsoptimalisering i PostgreSQL-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Velge partisjoneringsnøkkel og strategi
  2. Partisjonsbeskjæring ved planlegging og kjøring
  3. Automatisere opprettelse og oppbevaring av partisjoner
  4. Migrere en enorm tabell til partisjoner uten nedetid
← Tilbake til Ytelse og spørringsoptimalisering i PostgreSQL