Prestaties en queryoptimalisatie in PostgreSQL · Les

TOAST-internals en opslag van grote waarden

Begrijp hoe PostgreSQL te grote kolommen opslaat en stem compressie en drempels voor externe opslag af.

Les 4 van 413 stappen

TOAST-internals en opslag van grote waarden is een gratis Prestaties en queryoptimalisatie in PostgreSQL-les op CoddyKit. Dit is les 4 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Prestaties en queryoptimalisatie in PostgreSQL. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Prestaties en queryoptimalisatie in PostgreSQL bevat in totaal 4 lessen.

Waarom TOAST bestaat

PostgreSQL slaat rijen op in pagina's van vaste grootte: 8 KB. Eén rij kan niet over meerdere pagina's worden verdeeld, waardoor een brede waarde (een lange text, grote jsonb of bytea) nooit zou passen.

TOAST (The Oversized-Attribute Storage Technique) lost dit op door te grote kolommen te comprimeren en ze, als ze daarna nog te groot zijn, in stukken op te delen die in een aparte hulp-tabel worden opgeslagen.

  • Houdt de rij in de hoofdopslag klein en cachevriendelijk.
  • Maakt het mogelijk dat een logische waarde veel groter is dan 8 KB (tot ongeveer 1 GB).
  • Gebeurt automatisch en transparant voor je query's.

De TOAST-drempel

TOAST wordt gebruikt wanneer de totale grootte van een rij groter zou worden dan TOAST_TUPLE_THRESHOLD, standaard 2 KB (een kwart van de pagina van 8 KB).

Wanneer die limiet wordt overschreden, comprimeert PostgreSQL de grootste toastbare attributen en/of verplaatst het die buiten de rij, totdat de rij onder TOAST_TUPLE_TARGET past (eveneens ongeveer 2 KB).

Alleen kolommen met typen met variabele lengte (text, varchar, jsonb, bytea, arrays enzovoort) zijn toastbaar. Typen met een vaste lengte, zoals integer of timestamptz, worden nooit met TOAST opgeslagen.

De TOAST-tabel vinden

Elke tabel met minstens één toastbare kolom krijgt een bijbehorende TOAST-tabel met de naam pg_toast.pg_toast_<oid>. Je kunt die tabel in de catalogus vinden.

De kolom reltoastrelid koppelt een heaprelatie aan de bijbehorende TOAST-relatie; de waarde 0 betekent dat er geen TOAST-tabel is aangemaakt.

SELECT c.relname,
       c.reltoastrelid,
       t.relname AS toast_table
FROM pg_class c
LEFT JOIN pg_class t ON t.oid = c.reltoastrelid
WHERE c.relname = 'documents';

De vier opslagstrategieën

Elke kolom heeft een opslagstrategie die bepaalt of de kolom kan worden gecomprimeerd en/of buiten de rij kan worden opgeslagen:

  • PLAIN — geen compressie en geen opslag buiten de rij; alleen geldig voor niet-toastbare typen.
  • EXTENDED — zowel compressie als opslag buiten de rij toestaan (standaard voor de meeste typen met variabele lengte).
  • EXTERNAL — opslag buiten de rij toestaan, maar geen compressie (snellere toegang tot substrings).
  • MAIN — compressie toestaan, maar de gegevens in de hoofdtafel houden tenzij dat absoluut noodzakelijk is.

Opslag per kolom controleren

Vraag pg_attribute.attstorage op om de strategie van elke kolom te bekijken. De codes betekenen: p=PLAIN, e=EXTERNAL, m=MAIN, x=EXTENDED.

SELECT attname,
       atttypid::regtype AS type,
       CASE attstorage
         WHEN 'p' THEN 'plain'
         WHEN 'e' THEN 'external'
         WHEN 'm' THEN 'main'
         WHEN 'x' THEN 'extended'
       END AS storage
FROM pg_attribute
WHERE attrelid = 'documents'::regclass
  AND attnum > 0
  AND NOT attisdropped;

De strategie van een kolom wijzigen

Gebruik ALTER TABLE ... SET STORAGE om de standaardinstelling te overschrijven. Een veelgebruikte optimalisatie: als je regelmatig willekeurige substrings uit een grote bytea leest (bijvoorbeeld bereiklezingen uit een blob), schakel je over naar EXTERNAL. Waarden worden dan ongecomprimeerd opgeslagen en gedeeltelijk opgehaald zonder de hele waarde te decomprimeren.

De nieuwe strategie geldt alleen voor rijen die na de wijziging worden geschreven; bestaande gegevens worden pas herschreven wanneer ze worden bijgewerkt.

ALTER TABLE documents
  ALTER COLUMN payload SET STORAGE EXTERNAL;

-- Force a rewrite to apply it to existing rows:
VACUUM FULL documents;

Compressiealgoritmen: pglz versus lz4

PostgreSQL comprimeert TOAST-waarden voordat het opslag buiten de rij overweegt. Er zijn twee algoritmen beschikbaar:

  • pglz — de historische ingebouwde optie, met een redelijke verhouding maar lagere snelheid.
  • lz4 — beschikbaar sinds PostgreSQL 14, met veel snellere compressie en decompressie maar een iets lagere verhouding. Vereist dat de server met lz4-ondersteuning is gebouwd.

De standaardinstelling voor het hele cluster wordt bepaald door default_toast_compression.

SHOW default_toast_compression;

-- Set lz4 cluster-wide (postgresql.conf or per session):
SET default_toast_compression = 'lz4';

Compressie per kolom

Vanaf PostgreSQL 14 kun je de compressiemethode voor afzonderlijke kolommen instellen met SET COMPRESSION. Dit staat los van de opslagstrategie.

Kies lz4 voor vaak gebruikte, grote kolommen waarbij CPU-gebruik tijdens lezen en schrijven belangrijk is; behoud pglz of gebruik EXTERNAL wanneer de compressieverhouding of toegang tot substrings belangrijker is.

ALTER TABLE documents
  ALTER COLUMN body SET COMPRESSION lz4;

-- Inspect chosen method per column:
SELECT attname, attcompression
FROM pg_attribute
WHERE attrelid = 'documents'::regclass
  AND attnum > 0;

Het doel voor opslag buiten de rij afstemmen

De reloptie toast_tuple_target bepaalt hoe agressief PostgreSQL attributen buiten de rij plaatst: de optie stelt de grootte in waar de hoofdtuple naartoe wordt verkleind (geldig bereik: 128 bytes tot ongeveer 8160).

Als je deze waarde verlaagt, worden meer waarden eerder naar TOAST verplaatst. Daardoor blijft de hoofdopslag dicht en verbeteren scans wanneer de grote kolommen zelden worden gelezen. Als je de waarde verhoogt, blijft meer gegevens inline staan.

ALTER TABLE documents
  SET (toast_tuple_target = 512);

-- Verify current reloptions:
SELECT reloptions
FROM pg_class
WHERE relname = 'documents';

De TOAST-voetafdruk meten

Gebruik de groottefuncties om bytes in de hoofdtafel te onderscheiden van TOAST-bytes. Zo zie je of de opgeblazen opslag in de heap of in te grote waarden zit.

  • pg_table_size — heap + TOAST + de TOAST-indexen daarvan, exclusief gewone indexen.
  • pg_relation_size(rel, 'main') — alleen de hoofdfork.
SELECT
  pg_size_pretty(pg_relation_size('documents'))        AS heap,
  pg_size_pretty(
    pg_total_relation_size(reltoastrelid)
  )                                                     AS toast,
  pg_size_pretty(pg_total_relation_size('documents'))  AS total
FROM pg_class
WHERE relname = 'documents';

Praktische gevolgen voor de prestaties

TOAST blijft onzichtbaar totdat dat niet meer zo is. Houd rekening met deze belangrijke effecten:

  • Het lezen van een kolom die met TOAST is opgeslagen veroorzaakt extra indexopzoekingen in de TOAST-tabel en mogelijk decompressie — vermijd SELECT * wanneer je alleen kleine kolommen nodig hebt.
  • Waarden blijven bij updates met TOAST opgeslagen als ze niet worden gewijzigd, waardoor niet-gerelateerde updates goedkoop zijn.
  • EXTERNAL maakt efficiënte substr()- en bereiklezingen van grote ongecomprimeerde blobs mogelijk.
  • Overschakelen van pglz naar lz4 kan het CPU-gebruik voor schrijven sterk verminderen bij werklasten met veel invoegingen van grote waarden.

Korte controle

Je hebt een tabel waarvan de grote bytea-kolom meestal wordt gelezen met substr() voor kleine bytebereiken. Deze lezingen zijn traag omdat bij elke toegang de volledige waarde wordt gedecomprimeerd. Welke afzonderlijke wijziging lost dit het beste op?

Samenvatting

Je hebt geleerd hoe PostgreSQL te grote waarden verwerkt:

  • TOAST wordt geactiveerd wanneer een rij groter zou worden dan de drempel van ongeveer 2 KB. Grote kolommen met variabele lengte worden dan eerst gecomprimeerd en vervolgens verplaatst naar pg_toast.*-tabellen.
  • Vier strategieën — PLAIN, MAIN, EXTENDED (standaard) en EXTERNAL — bepalen compressie en opslag buiten de rij; je stelt ze in met ALTER TABLE ... SET STORAGE.
  • lz4 (PG14+) biedt snellere compressie dan pglz; kies dit per kolom met SET COMPRESSION of voor het hele cluster via default_toast_compression.
  • toast_tuple_target bepaalt hoe snel waarden de heap verlaten; met groottefuncties zie je hoeveel opslag in TOAST zit.
  • Kies EXTERNAL voor substring- en bereiklezingen, lz4 voor grote waarden bij veel schrijfwerk en vermijd SELECT * om onnodige decompressie van TOAST-waarden te voorkomen.
Gratis beginnen

Leer SQL met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
22
Lessen
88

Veelgestelde vragen

Is de les “TOAST-internals en opslag van grote waarden” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad Prestaties en queryoptimalisatie in PostgreSQL, waaronder “TOAST-internals en opslag van grote waarden”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus Prestaties en queryoptimalisatie in PostgreSQL bevat in totaal 4 lessen.

Wat leer ik in “TOAST-internals en opslag van grote waarden”?

Begrijp hoe PostgreSQL te grote kolommen opslaat en stem compressie en drempels voor externe opslag af. Je oefent met Prestaties en queryoptimalisatie in PostgreSQL door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Prestaties en queryoptimalisatie in PostgreSQL te beginnen?

Ervaring vooraf is niet nodig. Prestaties en queryoptimalisatie in PostgreSQL op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “TOAST-internals en opslag van grote waarden”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Prestaties en queryoptimalisatie in PostgreSQL?

Ja. Elke les over Prestaties en queryoptimalisatie in PostgreSQL bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Table- en index-bloat nauwkeurig meten
  2. Ruimte terugwinnen met pg_repack
  3. Fillfactor afstemmen voor update-intensieve tabellen
  4. TOAST-internals en opslag van grote waarden
← Terug naar Prestaties en queryoptimalisatie in PostgreSQL