Spaltenorientierte Datenbanken sind unglaublich schnell. Deshalb.

BBetter Stack
Computing/Software

Transcript

00:00:00Obwohl ich Postgres absolut liebe, ist es nicht für alles die beste Wahl. Es gibt eine andere Art von
00:00:04Datenbank, eine spaltenorientierte Datenbank, die bestimmte Abfragen bis zu 40 Mal schneller ausführen kann. Diese
00:00:10Datenbanken speichern Spalten zusammen anstatt Zeilen, wodurch man enorme Vorteile
00:00:15für bestimmte Anwendungsfälle wie Analyseplattformen erhält. Natürlich ist das Ganze mit Kompromissen verbunden,
00:00:20aber heute schauen wir uns genau an, was spaltenorientierte Datenbanken sind, und vergleichen einige Abfragen mit
00:00:25Postgres, um die Vor- und Nachteile zu sehen. Wir vergleichen Postgres mit ClickHouse und DuckDB,
00:00:31bleibt also dran, damit ihr am Ende ein solides Verständnis von spaltenbasierten Datenbanken habt
00:00:36und wisst, wann ihr zur richtigen Technologie greifen müsst.
00:00:43Am Anfang sagte ich also, man kann bestimmte Abfragen 40 Mal schneller ausführen, und das stimmt. Wenn wir uns
00:00:49eine Datenbanktabelle ansehen – hier habe ich hundert Millionen Zeilen geladen –, und ich führe eine Group-by-Abfrage mit
00:00:55Postgres aus, dauert das ungefähr 9,7 Sekunden, da wir den Umsatz aus jeder einzelnen
00:01:00Zeile aggregieren. Wenn wir dieselbe Abfrage über denselben Datensatz mit einer spaltenorientierten Datenbank ausführen – und zwar
00:01:06mit buchstäblich exakt demselben SQL (sowohl ClickHouse als auch DuckDB haben eine Postgres-ähnliche SQL-Syntax, sodass es sich
00:01:13bereits vertraut anfühlt) –, kommt ClickHouse auf 0,28 Sekunden und DuckDB auf 0,24 Sekunden. Das ist über 40 Mal schneller!
00:01:22Wie ist das möglich? Es scheint unglaublich, oder? Dieselben 100 Millionen Zeilen in nur 0,24 Sekunden.
00:01:30Spaltenbasierte Datenbanken verrichten einfach Größenordnungen weniger Arbeit, um uns dieselben Ergebnisse zu liefern.
00:01:36Sehen wir uns eine weitere Abfrage in Aktion an. Nur ein kurzer Hinweis, Leute: Wir veröffentlichen ständig Inhalte zu KI und Tech,
00:01:42also abonniert Better Stack, wenn euch das gefällt. Diesmal zählen wir die Anzahl
00:01:47der Ereignisse zwischen zwei Zeitstempeln, bei denen der Ländercode „gb“ lautet. In unserem Fall betrachten wir die Daten im
00:01:53März. Die Ergebnisse: Postgres bei 5,9 Sekunden, ClickHouse bei 0,06 Sekunden und DuckDB bei 0,03 Sekunden. Der März enthält
00:02:02etwa 13 Prozent der Gesamtereignisse hier, Postgres muss sich also immer noch Millionen von Zeilen ansehen. Wir könnten
00:02:09hier eine aggressive Indizierung hinzufügen, um zu helfen, aber das bringt uns nicht annähernd an ClickHouse und DuckDB heran. Warum
00:02:15sind Spaltenspeicher hier also so viel schneller? Nun, ClickHouse indiziert einzelne Zeilen überhaupt nicht. Wenn man
00:02:20eine Tabelle erstellt, gibt man ihr einen Sortierschlüssel, und die Daten werden nach Zeitstempel sortiert. Dann werden die sortierten Daten in Blöcke aufgeteilt –
00:02:32und es wird einfach der erste Zeitstempel in jedem Block notiert. Bei 100 Millionen Zeilen sind das etwa 12.000 Notizen,
00:02:39und das ist klein genug, um im Arbeitsspeicher zu bleiben. Wenn wir also nach dem März fragen, wird eine schnelle Suche durch diese
00:02:44Notizen durchgeführt, die Blöcke gefunden, die den März enthalten könnten, und es werden nur diese gelesen. In unserem Fall sind das 1.633 Blöcke von
00:02:5212.208, und alles andere auf der Festplatte wird übersprungen. DuckDB macht etwas Ähnliches, da es einen Min-
00:03:00und Maximalwert für jeden Chunk einer Spalte speichert. Wir können uns also einen Chunk ansehen, sehen, dass die Zeitstempel von Januar bis
00:03:06Februar laufen, und das Ganze überspringen, ohne es zu lesen. Rechnet man dazu den Trick von vorhin, dass nur
00:03:10die benötigten Spalten geöffnet werden, kommt man auf 0,03 Sekunden. Doch die Dinge nehmen eine komplette Kehrtwende, wenn man
00:03:17eine einzelne Zeile nach ID auswählen möchte. Diese einfache Abfrage offenbart einiges: Postgres braucht zwei Millisekunden, ClickHouse 168
00:03:26Millisekunden und DuckDB liegt interessanterweise immer noch bei zwei Millisekunden. Postgres hat einen B-Baum-Index auf der
00:03:32ID, geht also den Baum hinunter, landet auf der einen Seite, die die Zeile enthält, und ist in nur zwei
00:03:37Millisekunden fertig. Aber mit ClickHouse haben wir ein Problem: Der einzige Index ist dieser Sortierschlüssel, und diese Tabelle ist
00:03:43zuerst nach Zeitstempel und an zweiter Stelle nach ID sortiert. Wenn wir also nach einer einzelnen ID fragen, hat es keine Ahnung, in welchem Block diese ID
00:03:51liegt, und am Ende werden alle 12.208 Blöcke überprüft. Sobald die Zeile gefunden wurde, muss es immer noch
00:03:57alle acht Spaltendateien öffnen und diese Zeile wieder zusammenfügen, was eine Menge Arbeit für eine so
00:04:03einfache Abfrage ist. Wie kommt DuckDB also damit davon? Es hatte Glück mit unseren Daten: Die IDs wurden der
00:04:09Reihe nach eingefügt, sodass der Min- und Maximalwert jedes Chunks ordentlich mit der ID übereinstimmt und DuckDB direkt zur richtigen
00:04:16springen kann. Wären die IDs durcheinandergewürfelt worden, würde es genau wie ClickHouse die gesamte Spalte durchsuchen. Schauen wir uns nun
00:04:21das Aktualisieren einer Zeile an. Wir haben eine Abfrage für Postgres und DuckDB und eine etwas andere Version für
00:04:26ClickHouse. Postgres lag bei fünf Millisekunden, ClickHouse bei 5,8 Sekunden und DuckDB wiederum bei nur Dutzenden
00:04:34von Millisekunden. Postgres schreibt einfach eine Zeile neu und aktualisiert einen Indexeintrag. In ClickHouse sind die Datendateien
00:04:40unveränderlich, sie werden niemals an Ort und Stelle bearbeitet. Um also einen einzigen Umsatzwert zu ändern, muss die
00:04:46gesamte Spaltendatei für diesen Tabellen-Chunk neu geschrieben werden. ClickHouse zwingt einen sogar dazu, dies als
00:04:51ALTER TABLE zu schreiben, da es dies als Mutation der gesamten Tabelle behandelt. Es gibt ein leichteres Update in
00:04:56der Beta, aber das ist nur für kleine Mengen von Zeilen gedacht – höchstens etwa 10 % der Tabelle. DuckDB liegt genau
00:05:03zwischen den beiden, da seine Datei an Ort und Stelle geändert werden kann, sodass ein Update einer einzelnen Zeile ein paar Dutzend
00:05:08Millisekunden dauert. Und schließlich zählen wir die Anzahl der unterschiedlichen Benutzer in unserer Tabelle – wieder eine leichte
00:05:14Abweichung der Abfrage für ClickHouse –, und die Ergebnisse lauten: Postgres 38,4 Sekunden, ClickHouse 0,78 Sekunden
00:05:22und DuckDB unter einer Sekunde. Wieder leidet Postgres darunter, dass die Aggregation über eine so große Tabelle
00:05:28einfach eine enorme Menge an Arbeit erfordert. Nun möchte man spaltenorientierte Datenbanken oft für Dinge wie Analysen verwenden,
00:05:34bei denen das Aggregieren von Daten über verschiedene Spalten hinweg eine gängige Aufgabe ist. Hier haben wir uns zwei Optionen angesehen: ClickHouse
00:05:41ist ein gehosteter Server, Open Source und auf den meisten großen Plattformen verfügbar. Um dies lokal auszuführen, muss man
00:05:47einen ClickHouse-Server auf dem eigenen Rechner laufen lassen, was der Funktionsweise von Postgres viel ähnlicher ist. DuckDB hingegen ist eher wie SQLite:
00:05:54Es ist eine Bibliothek, die in ihrem eigenen Prozess läuft, und die gesamte Datenbank befindet sich in einer einzigen Datei auf der Festplatte. Diese
00:06:00Datei kann also gesperrt werden, während ein Update läuft, was die Nebenläufigkeit einschränkt. Beide sind spaltenorientierte
00:06:06Datenbanken, verfolgen aber sehr unterschiedliche Ansätze. Welche Datenbank ihr am Ende nutzt, hängt also von viel mehr ab,
00:06:12als ich hier annehmen kann. Es geht nicht nur um die rohe Abfragegeschwindigkeit beim Ausführen von Demos auf dem lokalen Rechner,
00:06:17sondern um Skalierbarkeit, Redundanz und Erweiterbarkeit. Natürlich verfügt Postgres über ein reichhaltiges Plugin-Ökosystem,
00:06:24um seinen Funktionsumfang auf viele Arten zu erweitern, was ihr in diesem nächsten Video sehen könnt.

Key Takeaway

Spaltenorientierte Datenbanken beschleunigen analytische Aggregationen über große Datenmengen um das Vierzigfache, schwächeln jedoch bei einzelnen Zeilenupdates und Punktabfragen im Vergleich zu Postgres.

Highlights

  • Spaltenorientierte Datenbanken wie ClickHouse und DuckDB verarbeiten aggregierte Abfragen über 100 Millionen Zeilen in unter 0,3 Sekunden, verglichen mit 9,7 Sekunden bei Postgres.

  • ClickHouse speichert keine Zeilenindizes, sondern nutzt Sortierschlüssel und Blocknotizen im Arbeitsspeicher, um nicht relevante Festplattendaten komplett zu überspringen.

  • Bei der Abfrage einzelner Zeilen nach ID benötigt Postgres 2 Millisekunden dank B-Baum-Index, während ClickHouse 168 Millisekunden erfordert, da alle Blöcke durchsucht und Spaltendateien zusammengefügt werden müssen.

  • Wegen unveränderlicher Datendateien erfordert ein einzelnes Zeilenupdate in ClickHouse eine vollständige Neuschreibung des Spalten-Chunks und dauert 5,8 Sekunden.

  • DuckDB agiert als In-Process-Bibliothek ähnlich wie SQLite, während ClickHouse als eigenständiger Server läuft.

Timeline

Leistungsvergleich bei großen Aggregationen

  • Postgres benötigt für eine Group-by-Abfrage über 100 Millionen Zeilen 9,7 Sekunden.
  • ClickHouse und DuckDB führen dieselbe SQL-Abfrage in 0,28 beziehungsweise 0,24 Sekunden aus.
  • Spaltenspeicher reduzieren die Rechenarbeit für aggregierte Analysen um Größenordnungen.

Der Vergleich verdeutlicht die Grundstärke spaltenorientierter Datenbanken. Während zeilenorientierte Systeme wie Postgres jede Zeile komplett einlesen müssen, verarbeiten spaltenorientierte Systeme nur die konkret angeforderten Attribute.

Technische Funktionsweise und Filterung

  • Die Filterung nach Zeitstempel und Ländercode dauert bei Postgres 5,9 Sekunden, bei ClickHouse 0,06 Sekunden und bei DuckDB 0,03 Sekunden.
  • ClickHouse indiziert keine einzelnen Zeilen, sondern speichert den ersten Zeitstempel von sortierten Datenblöcken im Arbeitsspeicher.
  • DuckDB nutzt Minimal- und Maximalwerte pro Spalten-Chunk, um irrelevante Datenbereiche ohne Festplattenzugriff zu verwerfen.

Durch die Block-Metadaten erkennen spaltenbasierte Systeme sofort, welche Datenblöcke einen bestimmten Zeitraum wie den März enthalten. Dadurch überspringen sie tausende irrelevante Blöcke auf der Festplatte vollständig.

Nachteile bei Punktabfragen und Updates

  • Postgres verarbeitet die Abfrage einer einzelnen ID in 2 Millisekunden über einen B-Baum-Index.
  • ClickHouse benötigt für dieselbe ID 168 Millisekunden, da sämtliche Blöcke geprüft und acht Spaltendateien zusammengefügt werden müssen.
  • Ein Zeilenupdate dauert in Postgres 5 Millisekunden, in ClickHouse jedoch 5,8 Sekunden wegen unveränderlicher Dateien.

Punktabfragen und Schreibvorgänge offenbaren die Schwachstellen von Spaltenspeichern. Da Daten spaltenweise getrennt liegen, erfordert das Zusammenfügen einzelner Zeilen oder das Neuschreiben ganzer Chunks bei Mutationen massiven Rechenaufwand.

Architektur und Einsatzbereiche

  • Die Zählung unterschiedlicher Benutzer erfordert bei Postgres 38,4 Sekunden und bei ClickHouse 0,78 Sekunden.
  • ClickHouse funktioniert als gehosteter Server, während DuckDB als In-Process-Bibliothek wie SQLite arbeitet.
  • Die Auswahl der optimalen Datenbank hängt neben der Abfragegeschwindigkeit von Skalierbarkeit, Ökosystem und Architektur ab.

Analyseanwendungen profitieren massiv von spaltenorientierten Systemen, während relationale Standarddatenbanken wie Postgres universeller einsetzbar bleiben und ein breites Plugin-Ökosystem bieten.

Community Posts

No posts yet. Be the first to write about this video!

Write about this video