„TOASTen“ mit PostgreSQL

toast-titel

TOAST – The Oversized-Attribute Storage Technique

Daten einer Tabelle werden in PostgreSQL bekannterweise in Blöcken abgelegt. Die Datenbank nutzt dabei Blockgrößen von standardmäßig 8 kByte bis maximal 32 kByte, welche anfangs beim Kompilieren der Datenbanksoftware festgelegt wird. Die Länge eine Zeile war zunächst auf die Größe eines Blockes beschränkt. Das heißt, bei breiten Tabellen mit vielen Spalten und großen Character-Feldern kam man schnell an seine Grenzen. Mit TOAST (The Oversized-Attribute Storage Technique) wurde dem seit Version 7.1. Abhilfe geschaffen. Seitdem ist es auch möglich, größere Datenmengen abzulegen, ohne etwa in diesem Fall auf Large Objects ausweichen zu müssen.

Die Arbeitsweise von TOAST

TOAST kann als eine Kombination aus Datenkomprimierung und Auslagern von Daten in eine Hilfstabelle angesehen werden. Beim Erstellen einer Tabelle, welche Felder mit variabler Länge wie VARCHAR, TEXT oder ARRAY enthält, wird automatisch eine TOAST-Hilfstabelle angelegt. Ab einer bestimmten Größe werden nun beim Einfügen von Daten diese „breiten" Spalten in der Hilfstabelle abgelegt, welche sich außerhalb des ursprünglichen Blockes befinden. Je nach Größe der Felder, werden die Daten dabei noch nach bestimmten Regeln komprimiert, um Plattenplatz zu sparen. Der Anwender selbst bekommt von dieser im Hintergrund laufenden Aktion gar nichts mit, da dies automatisch von PostgreSQL erledigt wird.

Der Administrator ist jedoch selbstverständlich in der Lage, darüber einen Überblick zu bekommen, indem z.B. verschiedene Infos aus den Systemtabellen abgefragt werden.

Die „geTOASTen" Tabellen

Die „geTOASTeten" Tabellen haben immer folgende Namenskonvention im Systemkatalog: pg_toast_<oid> Damit ist es leicht, die ausgelagerten Tabellen anhand des Object Identifiers (OID) der Haupttabelle zu finden.
All diese TOAST-Tabellen haben immer die gleiche Struktur, d.h. die gleichen drei Spalten:
CHUNK_ID: Hier ist der OID der Haupttabelle abgelegt.
CHUNK_SEQ: Jeder Chunk erhält eine sequenzielle Nummer, welche hier abgelegt wird.
CHUNK_DATA: Die Spalte enthält die eigentlichen Daten. Diese sind in einem komprimierten Binärformat abgelegt, sind daher also nicht wirklich durch das Selektieren der Spalte auf der TOAST-Tabelle lesbar.
Ein Index (pg_toast_<oid>_index ), welcher automatisch auf die Spalten CHUNK_ID und CHUNK_SEQ angelegt wird, garantiert einen schnellen Zugriff auf die eigentlichen Daten.

Performancevorteile

Im Wesentlichen ergeben sich aus diesem Konzept zwei Vorteile:
Beim Lesen von Daten müssen die TOAST-Spalten nicht gelesen werden, wenn diese nicht selektiert werden. Es findet also ggf. deutlich weniger I/O statt, was natürlich schneller ist.
Weiterhin kann eine Aktualisierung auf eine Spalte unter Umständen performanter sein. Wird beim klassischen Konzept die veraltete Zeile als „veraltet" markiert und ein neuer Datensatz auf die Seite geschrieben, wird bei TOAST niemals eine „geTOASTete" Spalte gelesen: Werden die nicht ausgelagerten Daten verändert, so ändert sich lediglich die Referenz auf die ausgelagerten Spalten. Beim Ändern einer ausgelagerten Spalte muss diese lediglich neu geschrieben werden und ebenso die Referenz neu gesetzt werden. D.h. die Update-Anweisung muss weniger Daten lesen und schreiben als beim klassischen Konzept, wodurch sich Performanceverbesserungen ergeben.

Manuelles „TOASTen"

Nicht jeder möchte es der Datenbank überlassen wann „geTOASTet" wird und wann nicht. Dazu kann selbstverständlich auch explizit angegeben werden, wie die Daten denn nun abgelegt werden sollen
Dies passiert mit dem ALTER TABLE Kommando und der SET STORAGE Option:

Syntax:
ALTER TABLE ALTER [ COLUMN ] <spalte>
SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }

Für jede einzelne Spalte lässt sich so beeinflussen, wie die Daten abgelegt werden. Dabei stehen vier Optionen zur Auswahl:

PLAIN:
Die Daten werden unkomprimiert innerhalb des Blockes, also in der Haupttabelle, gespeichert. Spalten mit einer fixen Datenlänge wie z.B. INTEGER Werte können nur als PLAIN abgelegt werden. Umgekehrt kann es jedoch auch sein, dass große, breite Datenfelder wie VARCHAR ggf. nicht als PLAIN abgelegt werden können.

EXTERNAL:
Die Spalten werden unkomprimiert in eine TOAST-Hilfstabelle ausgelagert.

EXTENDED:
Diese Option ist die Standardeinstellung beim Anlegen einer Tabelle. Hier entscheidet PostgreSQL selbstständig anhand der Größe, ob eine Spalte komprimiert wird und/oder die Spalte in eine TOAST-Hilfstabelle ausgelagert wird.

MAIN:
Die Daten werden komprimiert gespeichert, wenn der Datentyp Komprimierung unterstützt, also in der Regel VARCHAR Felder.

Prüfen

Ob und wie einzelne Spalten nun „geTOASTet" wurden oder nicht, lässt sich am einfachsten mit dem \d+ Kommando prüfen:

postgres=# create table toast_test (id integer, message text);
CREATE TABLE
postgres=# \d+ toast_test
                                        Tabelle »public.toast_test«
 Spalte  |   Typ   | Sortierfolge | NULL erlaubt? | Vorgabewert | Speicherung | Statistikziel | Beschreibung
---------+---------+--------------+---------------+-------------+-------------+---------------+--------------
 id      | integer |              |               |             | plain       |               |
 message | text    |              |               |             | extended    |               |

postgres=#
 

Fazit

Mit TOAST wurde in PostgreSQL ein gutes Konzept implementiert, mit welchem sich durchaus gute Möglichkeiten ergeben, Daten effektiver und vor allem performanter abzulegen. Durch die Möglichkeit, Spalten individuell zu „TOASTen" oder nicht zu „TOASTen", lassen sich Tabellen genau nach den Bedürfnissen der Anwendung optimieren und verbessern.

By accepting you will be accessing a service provided by a third-party external to https://blog.ordix.de/