Sortkeys in Redshift: was die Reihenfolge auf der Platte wirklich spart
Der häufigste Irrtum bei Sortkeys ist, dass sie wie ein Index funktionieren. Tun sie nicht. Redshift legt keine zweite Struktur an, in der es nachschlägt. Es speichert die Zeilen schlicht in einer bestimmten Reihenfolge und merkt sich pro Block, welcher Wertebereich darin vorkommt. Der Gewinn entsteht nicht beim Suchen, sondern beim Weglassen.
Was beim Scan übersprungen wird
Redshift schreibt Spalten in Blöcke von einem Megabyte. Zu jedem Block hält es
eine Zone Map, also nur zwei Zahlen: den kleinsten und den größten Wert darin.
Kommt eine Abfrage mit WHERE bestelldatum = '2026-08-24', vergleicht Redshift
diese Bedingung zuerst gegen die Zone Maps und liest nur die Blöcke, deren
Bereich das Datum überhaupt enthalten kann.
Deklariert wird das beim Anlegen der Tabelle. Mehr als diese eine Zeile braucht es nicht:
CREATE TABLE bestellungen (
bestell_id BIGINT,
kunde_id BIGINT,
bestelldatum DATE NOT NULL,
betrag NUMERIC(12, 2)
)
DISTSTYLE KEY
DISTKEY (kunde_id)
COMPOUND SORTKEY (bestelldatum, kunde_id);Ob es wirkt, verrät SVV_TABLE_INFO. Interessant sind zwei Spalten: unsorted
sagt, welcher Anteil der Tabelle noch nicht in der Sortierreihenfolge liegt,
stats_off, wie veraltet die Statistiken sind.
SELECT "table", size, unsorted, stats_off
FROM svv_table_info
WHERE "table" = 'bestellungen';Compound oder Interleaved
Die Wahl zwischen beiden Varianten ist keine Geschmacksfrage, sondern hängt davon ab, wie die Abfragen aussehen, die tatsächlich laufen.
| Compound | Interleaved | |
|---|---|---|
| Sortiert nach | Spalten in der angegebenen Reihenfolge | allen Spalten gleich gewichtet |
| Stark bei | Filter auf der ersten Spalte, Joins, GROUP BY | wechselnden Filtern auf verschiedenen Spalten |
| Schwach bei | Filtern, die die erste Spalte auslassen | Tabellen, die häufig geladen werden |
| Pflegeaufwand | gering | hoch, VACUUM REINDEX wird teuer |
| Sinnvoll ab | fast immer die richtige Wahl | wenn Compound nachweislich nicht reicht |
Compound ist der Normalfall. Der Reihenfolge wegen gilt dabei dieselbe Regel wie bei einem zusammengesetzten Index in Postgres: Eine Bedingung auf der zweiten Spalte nützt wenig, solange die erste nicht eingegrenzt ist.
Wie deutlich der Unterschied ausfällt, hängt an der Selektivität des Filters. Die folgenden Zahlen stammen aus einem konstruierten Beispiel mit rund 240 Millionen Zeilen, sie sind zur Veranschaulichung gedacht und nicht als Benchmark:
Gelesene Datenmenge pro Abfrage, Gigabyte
| Ohne Sortkey | 41,6 | |
|---|---|---|
| Ungepflegt | 28,3 | |
| Nach VACUUM | 2,4 |
Wann Sortkeys nichts bringen
Es gibt Tabellen, bei denen sich der Aufwand nicht lohnt, und das zu erkennen spart mehr Zeit als jede Feinjustierung:
- Kleine Tabellen. Unterhalb weniger Blöcke pro Slice gibt es nichts zu überspringen. Dimensionstabellen mit ein paar tausend Zeilen gehören dazu.
- Abfragen ohne einschränkendes Prädikat. Wer ohnehin die ganze Tabelle aggregiert, liest sie ohnehin ganz.
- Filter auf einer Spalte mit wenigen verschiedenen Werten. Ein Sortkey auf einem Ja-Nein-Feld halbiert bestenfalls, und das auch nur einmal.
- Tabellen, die stündlich geladen und nie aufgeräumt werden. Siehe oben.
Die nützlichste Frage vor jedem Sortkey ist nicht, welche Spalte am häufigsten vorkommt, sondern welche Spalte am zuverlässigsten den größten Teil der Daten ausschließt.
Beides fällt oft zusammen, aber eben nicht immer. Und wo es auseinanderfällt, gewinnt die zweite Frage.