Candy Jack Hoffmann
Zurück zum Technical Blog
Redshift·4 Min. Lesezeit

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.

sortiert01.08 – 08.08übersprungen09.08 – 16.08übersprungen17.08 – 24.08gelesen25.08 – 31.08übersprungenunsortiert01.08 – 31.08gelesen02.08 – 30.08gelesen01.08 – 29.08gelesen03.08 – 31.08gelesen
Bei sortierten Daten deckt jeder Block einen engen Zeitraum ab, und die Bedingung trifft nur einen davon. Unsortiert streut derselbe Tag über alle Blöcke, und keiner lässt sich überspringen.

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.

CompoundInterleaved
Sortiert nachSpalten in der angegebenen Reihenfolgeallen Spalten gleich gewichtet
Stark beiFilter auf der ersten Spalte, Joins, GROUP BYwechselnden Filtern auf verschiedenen Spalten
Schwach beiFiltern, die die erste Spalte auslassenTabellen, die häufig geladen werden
Pflegeaufwandgeringhoch, VACUUM REINDEX wird teuer
Sinnvoll abfast immer die richtige Wahlwenn 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
Beispielwerte. Der Sprung entsteht nicht durch schnelleres Lesen, sondern dadurch, dass 94 Prozent der Blöcke nicht angefasst werden.

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.