ClickHouse wird noch träger und noch schneller – Einführung der Optimierung mit Lazy Materialization
(clickhouse.com)- ClickHouse führt mit lazy materialization eine neue Optimierungstechnik ein und verbessert damit die Performance von
Top N-Abfragen um bis zu 1.500-fach - Durch eine Strategie, bei der Spaltendaten nur bei Bedarf gelesen werden, wird die Festplatten-I/O minimiert
- Zusammen mit bestehenden Verfahren wie spaltenbasiertem Storage, Indizes und PREWHERE entsteht ein hierarchischer I/O-Optimierungs-Stack
- Durch das verzögerte Laden von Spaltendaten abhängig vom Query-Ausführungsplan ist der Effekt besonders groß, vor allem bei Abfragen mit LIMIT-Klausel
- Da die Funktion standardmäßig aktiviert ist, lassen sich Performance-Gewinne ohne Codeänderungen erzielen
ClickHouses verzögerte Optimierungsstrategie: Lazy Materialization
Kernkonzept
- ClickHouse maximiert die Performance, indem unnötige Daten gar nicht erst gelesen werden
- Lazy Materialization lädt Spaltendaten während der Query-Ausführung erst dann, wenn sie tatsächlich benötigt werden
- Das Verfahren arbeitet unabhängig von bestehenden I/O-Optimierungen und ergänzt diese mit zusätzlichem Performance-Gewinn
Bestehende I/O-Optimierungstechniken
- Spaltenbasierter Speicher: Es werden nur die benötigten Spalten gelesen
- Sparse Index / Skipping Index / Projections: Es werden nur Granules gelesen, die zu den Filterbedingungen passen
- PREWHERE: Frühes Filtern von nicht indizierten Spalten
- Query Condition Cache: Zwischenspeichert Ergebnisse wiederholter Abfragen, um die erneute Verarbeitung derselben Granules zu vermeiden
So funktioniert Lazy Materialization
- Während bisherige Techniken vor allem auf I/O-Reduktion durch Filterung abzielen, verschiebt Lazy Materialization das Lesen bis zum Zeitpunkt der Berechnung
- Es werden zunächst nur die Spalten gelesen, die für den nächsten Schritt der Query nötig sind, der Rest erst nach LIMIT, wenn er tatsächlich gebraucht wird
- Besonders bei Top N-Abfragen werden oft nur einige Spalten ausgewertet, sodass große Textspalten kaum gelesen werden müssen
> Diese Optimierung ist durch die unabhängige Speicherung von Spalten möglich und bei row-based DBs kein gangbarer Ansatz
Praxisbeispiel: Amazon-Review-Datensatz
-
150M rows, 70GB unkomprimiert, 30GB komprimiert
-
Beispiel für eine Top N-Abfrage:
SELECT helpful_votes FROM amazon.amazon_reviews ORDER BY helpful_votes DESC LIMIT 3;- Ausführungszeit: 0,07 Sekunden
- Schnelle Verarbeitung durch Abfrage nur einer einzelnen Spalte
-
Beispiel für das Abfragen einer großen Textspalte:
SELECT review_body FROM amazon.amazon_reviews FORMAT Null;- Ausführungszeit: 176 Sekunden
- Trotz nur einer Spalte entsteht mit 56GB ein Flaschenhals bei der Festplatten-I/O
Performance-Vergleich nach angewandter Optimierungsschicht
1. Keine Optimierung (Baseline)
- Ausführungszeit: 219 Sekunden
- Verarbeitungsmenge: 72GB, 150M rows
- Alle Spalten werden vollständig gelesen und sortiert
2. Einsatz des Primary Key Index
- Ausführungszeit: 96 Sekunden
- Verarbeitungsmenge: 28GB, 53M rows
- Granule-Filterung auf Basis des PK spart mehr als 50 % der Zeit
3. Zusätzliches PREWHERE
- Ausführungszeit: 61 Sekunden
- Verarbeitungsmenge: 16GB
- Zusätzliche I/O-Reduktion durch Anwendung von Filterbedingungen auf nicht indizierte Spalten
4. Lazy Materialization aktiviert
- Ausführungszeit: 0,18 Sekunden
- Verarbeitungsmenge: 807MB
- Aus großen Spalten werden am Ende nur die tatsächlich benötigten 3 rows geladen
> Insgesamt mehr als 1.200-fache Performance-Steigerung und mehr als 150-fach geringerer Speicherverbrauch
Auch für Top N-Abfragen ohne Filter wirksam
-
Bei einer Vollsortierungsabfrage ohne Filter:
SELECT helpful_votes, product_title, review_headline, review_body FROM amazon.amazon_reviews ORDER BY helpful_votes DESC LIMIT 3; -
Vor Lazy Materialization: 219 Sekunden
-
Nach Lazy Materialization: 0,139 Sekunden
-
1.576-fache Beschleunigung, 40-fach weniger I/O, 300-fach geringerer Speicherverbrauch
Ausführungsplan prüfen
EXPLAIN actions = 1
SELECT helpful_votes, product_title, review_headline, review_body
FROM amazon.amazon_reviews
ORDER BY helpful_votes DESC
LIMIT 3
SETTINGS query_plan_optimize_lazy_materialization = true;
- Ergebnis:
Lazily read columns: review_headline, review_body, product_title
Limit
Sorting
ReadFromMergeTree
- Große Spalten werden erst nach Sortierung und LIMIT geladen
Fazit
- Vervollständigung von ClickHouses I/O-Optimierungs-Stack: Index → PREWHERE → Lazy Materialization
- Ohne Codeänderungen lässt sich die Performance allein durch die Art der Query-Ausführung um Hunderte bis Tausende Male steigern
- Besonders ideal für Top N-Muster, große Spalten und LIMIT-Abfragen
- Da die Funktion standardmäßig aktiviert ist, wird sie automatisch angewendet, ohne dass Nutzer etwas konfigurieren müssen
> Dasselbe SQL, dieselbe Maschine, anderes Ergebnis
> Schneller = weniger lesen = ClickHouse
2 Kommentare
> Ich frage mich, ob jemand ClickHouse und StarRocks verglichen hat; vor ein paar Monaten schien die Join-Performance von StarRocks besser zu sein.
https://d2.naver.com/helloworld/1168674
Hacker-News-Kommentare
Diese Optimierung wird besonders bei der Entnahme zufälliger Stichproben aus großen Datensätzen dramatische Geschwindigkeitssteigerungen bringen, insbesondere wenn die gewünschten Spalten große Werte enthalten können
LIMIT-Klausel, um zu bestimmen, welche Zeilen in die Stichprobe aufgenommen werdenLIMIT-Klausel den Datensatz auf eine kleine Zahl von Zeilen gefiltert hatIch mag ClickHouse wirklich sehr
Ich kann Websites, auf denen man nicht scrollen kann, nicht verstehen
Late Materialization, 19 Jahre später
Hat nichts mit der neuen Materialisierungsoption zu tun, aber dieser Teil ist mir aufgefallen
ClickHouse wäre beliebter als DuckDB, wenn es ein natives Windows-Release gäbe, das weder WSL noch eine Linux-VM benötigt
Trotz des Flughafen-Dramas plane ich jetzt einen Strandurlaub
ClickHouse ist ein Meisterwerk moderner Ingenieurskunst
Ich frage mich, ob jemand ClickHouse mit StarRocks verglichen hat
Es ist erstaunlich, dass diese Datenbanken zeigen, was bei allen zeilenbasierten Datenbanken falsch läuft
chdb) zu verwenden