Zum Inhalt springen

Z-Ordering

Z-Ordering ist eine Data-Layout-Technik in Delta Lake, die per OPTIMIZE ZORDER BY korrelierte Werte mehrerer Spalten physisch in wenigen Dateien bündelt.

Z-Ordering ist eine Sortier-Technik für Delta-Lake-Tabellen (das offene Tabellenformat auf Basis von Parquet-Dateien im Objektspeicher). Beim Wartungs-Kommando OPTIMIZE ... ZORDER BY (spalte1, spalte2, ...) werden die Zeilen einer Tabelle physisch so neu geschrieben, dass ähnliche Werte mehrerer Spalten gemeinsam in denselben Dateien landen. Läuft danach eine Abfrage mit Filter auf diese Spalten, muss die Datenbank nur die wenigen Dateien lesen, deren Wertebereiche zum Filter passen; die übrigen Dateien überspringt sie (Data Skipping, das Auslassen nicht relevanter Dateien anhand von Statistik-Werten).

Was ist Z-Ordering?

Z-Ordering ist ein optionales Sortier-Verfahren für Delta-Lake-Tabellen (das offene Tabellenformat, das eine SQL-Tabelle als Menge von Parquet-Dateien plus Änderungs-Protokoll im Objektspeicher ablegt). Ausgelöst wird es über den SQL-Zusatz ZORDER BY (spalte1, spalte2, ...) innerhalb des Wartungs-Kommandos OPTIMIZE. Der Lauf liest die betroffenen Datendateien, berechnet für jede Zeile einen gemeinsamen Sortier-Wert über die genannten Spalten und schreibt die Zeilen anschließend in einer Reihenfolge zurück, in der ähnliche Werte in mehreren Spalten in denselben neuen Dateien liegen. Gleichzeitig aktualisiert Delta die pro Datei gespeicherten Statistiken (kleinster Wert, größter Wert, Anzahl leerer Felder je Spalte) im Änderungs-Protokoll (Transaction Log, die zentrale Metadaten-Historie einer Delta-Tabelle); auf diesen Statistiken beruht das Data Skipping der Abfrage-Engines.

Der Begriff stammt aus der Familie der raumfüllenden Kurven: Eine Z-Order-Kurve (auch Morton-Order) verbindet Punkte eines mehrdimensionalen Raums in einer Reihenfolge, die räumliche Nähe der Punkte in eine ähnliche Sequenznummer übersetzt. Praktisch entsteht der Z-Wert durch das bitweise Verschränken (Bit-Interleaving) der Binärdarstellungen mehrerer Spaltenwerte. Ähnliche Kurven-Familien wie die Hilbert-Kurve verhalten sich vergleichbar; Delta nutzt aus Implementierungsgründen die Z-Variante. Ohne Z-Ordering trägt eine einfache Sortierung (ORDER BY) nur für die erste Spalte, weil danach die Ordnung entlang der zweiten Spalte innerhalb der Sortier-Blöcke der ersten wieder zufällig wird.

Das Ziel ist Datei-Überspringen bei Queries mit Filtern auf mehreren Spalten. Läuft eine Query mit WHERE customer_id = 4711 AND event_date >= '2026-01-01', prüft die Query-Engine die Min/Max-Statistiken jeder Datei und liest nur die Dateien, deren Wertebereiche beide Predikate abdecken. Ohne Z-Layout überschneiden sich die Min/Max-Bereiche vieler Dateien auf beiden Filterspalten; nach Z-Ordering korrelieren die Wertebereiche pro Datei und die Zahl der zu lesenden Dateien sinkt oft um ein bis zwei Größenordnungen.

Z-Ordering war jahrelang die Standard-Empfehlung von Databricks für Tabellen mit Multi-Column-Filter-Mustern und ist Bestandteil des OSS-Delta-Formats. Seit Delta Lake 3.2 und Databricks Runtime 15.2 gilt Liquid Clustering als empfohlener Nachfolger für neue Tabellen, weil es dieselbe Wirkung inkrementell erreicht. Für bestehende Delta-Tabellen ohne Migration bleibt OPTIMIZE ... ZORDER BY weiterhin gültig und liefert reproduzierbare Ergebnisse, weil das Feature Teil der Delta-Spezifikation ist und von jeder konformen Reader-/Writer-Implementierung unterstützt wird.

Die Kostenrechnung bestimmt, wie oft ein Z-Ordering-Lauf sinnvoll ist. Jeder Lauf liest die betroffenen Dateien vollständig, rechnet die Z-Werte aus und schreibt die Dateien neu; der Compute-Aufwand skaliert mit der Datenmenge im Zielbereich, nicht mit der Änderungsmenge seit dem letzten Lauf. Übliche Muster sind ein wöchentlicher Lauf über die aktive Partition oder ein Lauf auf einen begrenzten Datumsbereich per WHERE-Prädikat, damit historische Daten nicht bei jedem Wartungsfenster neu geschrieben werden.

Abgrenzung zu Partitionierung, Liquid Clustering, Bloom Filter Index und Data Skipping Statistics

Z-Ordering wird häufig mit anderen Techniken vermischt, die entweder denselben Zweck über eine andere Mechanik verfolgen oder auf einer benachbarten Ebene der Delta-Optimierungs-Familie liegen.

BegriffKonzeptVerhältnis zu Z-Ordering
Hive-Style-Partitionierung (PARTITIONED BY)Statisches Ordner-Layout im Objektspeicher pro PartitionswertGrobkörniges Skipping auf Verzeichnisebene; nur eine feste Achse tragbar. Z-Ordering wirkt innerhalb der Datei-Menge, ohne Ordner-Struktur, und trägt mehrere Spalten gleichwertig.
Liquid Clustering (CLUSTER BY)Inkrementelles Cluster-Layout mit Metadaten-gestütztem NachführenNachfolger für denselben Zweck. Z-Ordering schreibt bei jedem OPTIMIZE-Lauf die betroffenen Dateien komplett neu; Liquid Clustering bearbeitet nur die Dateien, deren Statistiken vom Ziel-Layout abweichen.
Bloom Filter IndexProbabilistische Membership-Struktur pro Datei und SpalteBeantwortet die Frage „liegt dieser Wert sicher nicht in der Datei". Ergänzt Data Skipping bei Point-Lookups auf hoch-kardinalen Spalten, verändert das Datei-Layout aber nicht.
Data Skipping StatisticsMin/Max/Null-Count pro Spalte je Datei im Transaction LogBasis-Feature, auf dem Z-Ordering erst wirkt. Ohne Statistiken über die Ziel-Spalten bringt Z-Ordering keine Datei-Skips.

Der wichtigste Unterschied zu Liquid Clustering liegt in der Inkrementalität. Ein OPTIMIZE ... ZORDER BY-Lauf ist ein Full-Rewrite der betroffenen Dateien: Alle Zeilen, die im Z-Bereich neu einsortiert werden müssen, wandern in neu geschriebene Parquet-Dateien, unabhängig davon, wie klein die Änderungsmenge seit dem letzten Lauf war. Liquid Clustering merkt sich das Cluster-Layout in den Tabellen-Metadaten und bearbeitet gezielt nur die abweichenden Dateien. Bei Tabellen mit gleichmäßigem Ingest reduziert das Compute-Verbrauch und Laufzeit deutlich.

Gegenüber Partitionierung entfällt die Bindung an eine einzelne Achse. Partitionen sind Teil des Ordner-Layouts im Objektspeicher; ein Wechsel der Partitionsspalte erfordert einen Full-Table-Rewrite. Z-Ordering behandelt bis zu einigen wenigen Spalten gleichwertig und lässt sich pro OPTIMIZE-Lauf auf andere Spalten setzen, ohne die Ordner-Struktur der Tabelle zu ändern. Kombinationen sind möglich (Partition nach event_date, Z-Order nach customer_id, product_id innerhalb der Partition), waren aber in der Praxis oft schwer betreibbar; Liquid Clustering löst genau diesen Kombinations-Fall sauberer.

Beispiel: Nächtliche Wartung einer Delta-Faktentabelle mit Z-Ordering

Eine historische Faktentabelle im Gold-Layer speichert Bestellungen der letzten fünf Jahre in einer Delta-Tabelle. Analytische Queries filtern regelmäßig auf customer_id und event_date. Ein nächtlicher Wartungs-Job führt Z-Ordering aus, damit Data Skipping auf beiden Spalten greift:

sql
OPTIMIZE gold.fact_orders
  WHERE event_date >= current_date() - INTERVAL 90 DAYS
  ZORDER BY (customer_id, event_date);

Die WHERE-Klausel begrenzt den Rewrite auf die letzten 90 Tage; die älteren Partitionen bleiben unangetastet, weil sich ihre Daten kaum ändern. Ohne diese Begrenzung würde jeder Lauf die gesamte Tabelle neu schreiben. Nach dem OPTIMIZE liest eine Query wie SELECT SUM(amount) FROM gold.fact_orders WHERE customer_id = 4711 AND event_date >= '2026-06-01' nur die wenigen Dateien, deren Min/Max-Bereiche beide Predikate abdecken; die eingelesene Datenmenge sinkt entsprechend.

Auf einer neu angelegten Delta-Tabelle steht seit Databricks Runtime 15.2 Liquid Clustering als Alternative bereit. Statt OPTIMIZE ... ZORDER BY läuft dort CLUSTER BY (customer_id, event_date) bei der Tabellenerstellung und ein einfaches OPTIMIZE gold.fact_orders als Wartung; das Cluster-Layout wird inkrementell nachgeführt, unabhängig davon, wie viele Zeilen sich seit dem letzten Lauf geändert haben.

Z-Ordering im eigenen Unternehmen umsetzen?

Wir zeigen, wie sich das in deiner Systemlandschaft konkret abbilden lässt.

Gespräch vereinbaren