Ytelse og spørringsoptimalisering i PostgreSQL · leksjon

Justere fillfactor for tabeller med mange oppdateringer

Still inn fillfactor for å gi plass til HOT-oppdateringer og redusere indeksendringer på rader som endres ofte.

Leksjon 3 av 413 trinn

Justere fillfactor for tabeller med mange oppdateringer er en gratis leksjon i Ytelse og spørringsoptimalisering i PostgreSQL på CoddyKit. Dette er leksjon 3 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 oppdateringer er kostbare i PostgreSQL

PostgreSQL bruker MVCC: En UPDATE overskriver aldri en rad på stedet. I stedet skriver den en helt ny radversjon (tuppel) og markerer den gamle som foreldet.

  • Den nye tuppelen må plasseres et sted på disken.
  • Hvis den havner på en annen side enn den gamle versjonen, må alle indekser på tabellen oppdateres slik at de peker på den nye plasseringen.

På tabeller med mange oppdateringer blir denne indeksaktiviteten en viktig kilde til skriveforsterkning og bloat. I denne leksjonen ser du hvordan fillfactor kan hjelpe deg med å unngå dette.

Hva fillfactor faktisk styrer

fillfactor er en lagringsparameter for hver tabell (og indeks), angitt som en prosentverdi fra 10 til 100.

  • Den angir hvor full hver side på 8 KB skal pakkes når rader settes inn.
  • En fillfactor på 100 (standard for tabeller) fyller sidene helt.
  • En fillfactor på 90 lar omtrent 10 % av hver side stå som ledig plass reservert for fremtidige oppdateringer.

Denne reserverte plassen er nøkkelen til å muliggjøre rimeligere oppdateringer på samme side.

ALTER TABLE orders SET (fillfactor = 90);

HOT-oppdateringer: Gevinsten

En HOT-oppdatering (Heap-Only Tuple) skjer når:

  • Ingen av kolonnene som oppdateres, inngår i en indeks, OG
  • Den nye tuppelen får plass på samme side som den gamle.

Når begge vilkårene er oppfylt, lenker PostgreSQL den nye versjonen til den gamle inne på siden og hopper helt over oppdatering av indeksene. Ingen indeksaktivitet, langt mindre WAL, og den gamle versjonen kan ryddes bort effektivt av HOT-pruning.

Det er den ledige plassen som oppstår med en lavere fillfactor, som gjør betingelsen om «samme side» mulig.

Angi fillfactor for en ny tabell

Du kan angi lagringsparameteren når du bruker CREATE TABLE. Dette er den ryddigste metoden, fordi tabellen pakkes riktig helt fra første innsetting.

  • Velg en verdi som reserverer nok plass til det typiske antallet radversjoner på siden mellom hver vacuum-kjøring.
  • 90 er et vanlig utgangspunkt; 70–80 passer for svært aktive rader.
CREATE TABLE session_state (
    session_id   uuid PRIMARY KEY,
    last_seen_at timestamptz NOT NULL,
    hit_count    integer NOT NULL DEFAULT 0,
    payload      jsonb
) WITH (fillfactor = 80);

Endre fillfactor for en eksisterende tabell

ALTER TABLE ... SET (fillfactor = N) endrer parameteren, men skriver ikke eksisterende sider på nytt. Bare sider som skrives senere, følger den nye verdien.

For å bruke den på eksisterende data må du skrive tabellen på nytt med VACUUM FULL eller CLUSTER (begge tar en ACCESS EXCLUSIVE-lås), eller bruke pg_repack for en omskriving uten nedetid.

ALTER TABLE session_state SET (fillfactor = 80);
VACUUM FULL session_state;

Bekrefte at en HOT-oppdatering fant sted

Du trenger ikke gjette. pg_stat_user_tables viser tellere som forteller om oppdateringene dine følger HOT-stien.

  • n_tup_upd — totalt antall oppdaterte tupler.
  • n_tup_hot_upd — hvor mange av disse som var HOT-oppdateringer.

Et høyt forhold mellom n_tup_hot_upd / n_tup_upd betyr at fillfactor- og indeksutformingen din gir resultater.

SELECT relname,
       n_tup_upd,
       n_tup_hot_upd,
       round(100.0 * n_tup_hot_upd / NULLIF(n_tup_upd, 0), 1) AS hot_pct
FROM pg_stat_user_tables
WHERE relname = 'session_state';

Indekserte kolonner hindrer HOT-oppdateringer

Ledig plass alene er ikke nok. Hvis en UPDATE berører en hvilken som helst indeksert kolonne, må PostgreSQL opprette en ny indeksoppføring. Oppdateringen kan derfor aldri bli en HOT-oppdatering, selv om den nye tuppelen får plass på samme side.

  • Hold kolonner som oppdateres ofte (tellere, tidsstempler og statusflagg) utenfor indekser når det er mulig.
  • Fjern indekser du faktisk ikke trenger; hver av dem kan hindre HOT.

Eksempel: Hvis du indekserer hit_count, undergraver du hele poenget med å justere fillfactor for denne tabellen.

-- This index would block HOT updates whenever hit_count changes:
-- CREATE INDEX ON session_state (hit_count);

-- Prefer indexing stable columns instead:
CREATE INDEX idx_session_last_seen ON session_state (last_seen_at);

Velge en verdi: Avveiningen

Lavere fillfactor er ikke gratis. Avveiningene er:

  • Lavere fillfactor → mer ledig plass per side → flere HOT-oppdateringer og mindre indeksaktivitet → men tabellen bruker flere sider, slik at sekvensielle skanninger og bufferhurtigbufferen får plass til færre rader per side.
  • Høyere fillfactor → tettere lagring og bedre effektivitet for skanninger og hurtigbuffer → men oppdateringer flyttes til nye sider, noe som fører til indeksaktivitet og bloat.

Tommelfingerregel: Behold 100 for tabeller som bare får nye rader eller hovedsakelig leses. Gå ned til 70–90 bare for tabeller som faktisk oppdateres svært ofte.

fillfactor for indekser også

Indekser har sin egen fillfactor (standardverdien er 90 for B-tree). Hvis du senker den, blir det ledig plass på løvsidene, slik at nye oppføringer ikke fører til hyppige sidesplittinger i tabeller med mange innsettinger av monotonisk økende nøkler.

  • For nøkler som bare legges til eller stadig øker, er standardverdien vanligvis fin.
  • For indekser på tilfeldig fordelte nøkler med hyppige endringer kan en noe lavere fillfactor for indeksen redusere antallet sidesplittinger.
CREATE INDEX idx_session_last_seen
    ON session_state (last_seen_at)
    WITH (fillfactor = 80);

Kontrollere gjeldende innstillinger

For å se om en tabell allerede har en fillfactor som avviker fra standardverdien, les reloptions fra pg_class. NULL der betyr at standardverdien (100 for heap, 90 for B-tree) gjelder.

SELECT relname, reloptions
FROM pg_class
WHERE relname IN ('session_state', 'idx_session_last_seen');

En praktisk arbeidsflyt for justering

Slik kan du gå frem for en tabell med mange oppdateringer:

  • 1. Bekreft at arbeidsbelastningen hovedsakelig består av oppdateringer, og kontroller gjeldende forhold for n_tup_hot_upd.
  • 2. Flytt kolonner som endres ofte, ut av indeksene, og fjern ubrukte indekser.
  • 3. Angi fillfactor (start på 90, og senk mot 70 hvis HOT-forholdet fortsatt er lavt).
  • 4. Skriv om tabellen (VACUUM FULL / CLUSTER / pg_repack) slik at eksisterende sider får den nye pakkingen.
  • 5. Mål HOT-forholdet på nytt, og juster.

Valider alltid med statistikkvisningen – ikke juster i blinde.

ALTER TABLE session_state SET (fillfactor = 75);
CLUSTER session_state USING idx_session_last_seen;
ANALYZE session_state;

Rask kontroll

Du har en tabell med mange oppdateringer, der kolonnen status endres hele tiden, og du har senket fillfactor til 80 – men n_tup_hot_upd holder seg nær null. Hva er den mest sannsynlige årsaken?

Oppsummering

Dette er de viktigste punktene ved justering av fillfactor i tabeller med mange oppdateringer:

  • fillfactor reserverer ledig plass på hver side, slik at oppdaterte rader kan bli værende på samme side – noe som muliggjør HOT-oppdateringer.
  • HOT-oppdateringer hopper over indeksvedlikehold, noe som reduserer skriveforsterkning og oppblåsing.
  • HOT krever både plass på samme side og at ingen indeksert kolonne endres – hold derfor kolonner som endres ofte, utenfor indeksene.
  • ALTER TABLE SET (fillfactor=N) påvirker bare nye sider; skriv om tabellen med VACUUM FULL/CLUSTER/pg_repack for å bruke innstillingen på eksisterende data.
  • Mål resultatet med n_tup_hot_upd / n_tup_upd i pg_stat_user_tables, og juster trinnvis.
  • Lavere fillfactor bytter lagringstetthet mot færre oppdateringer som må over på nye sider – bruk det bare der arbeidsbelastningen tilsier det.
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 «Justere fillfactor for tabeller med mange oppdateringer» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Ytelse og spørringsoptimalisering i PostgreSQL, inkludert «Justere fillfactor for tabeller med mange oppdateringer», 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 «Justere fillfactor for tabeller med mange oppdateringer»?

Still inn fillfactor for å gi plass til HOT-oppdateringer og redusere indeksendringer på rader som endres ofte. 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 3 av 4.

Hvor lang tid tar leksjonen «Justere fillfactor for tabeller med mange oppdateringer»?

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. Måle tabell- og indeksbloat nøyaktig
  2. Gjenvinne plass med pg_repack
  3. Justere fillfactor for tabeller med mange oppdateringer
  4. Internt i TOAST og lagring av store verdier
← Tilbake til Ytelse og spørringsoptimalisering i PostgreSQL