2023-05-17
Ankündigung von DuckDB 0.8.0
Mark Raasveldt, Hannes Mühleisen

Das DuckDB-Team freut sich, das neueste DuckDB-Release (0.8.0) bekannt zu geben. Diese Version heißt „Fulvigula“ nach der Mottled Duck (Anas Fulvigula), die am Golf von Mexiko beheimatet ist.
Zur Installation der neuen Version siehe die Installationsanleitung. Die vollständigen Release Notes finden Sie auf GitHub.
Was ist neu in 0.8.0
Es gab zu viele Änderungen, um jede im Detail zu besprechen. Einige besonders spannende Features möchten wir aber hervorheben:
- Neue Pivot- und Unpivot-Statements
- Verbesserungen beim parallelen Datenimport und -export
- Time-Series-Joins
- Rekursives Globbing
- Lazy-Loading von Storage-Metadaten für schnellere Startzeiten
- Benutzerdefinierte Funktionen für Python
- Unterstützung für Arrow Database Connectivity (ADBC)
- Neue Swift-Integration
Im Folgenden eine Zusammenfassung dieser neuen Features mit Beispielen – beginnend mit zwei Breaking Changes in unserem SQL-Dialekt, die standardmäßig intuitivere Ergebnisse liefern sollen.
Breaking Changes in SQL
Dieses Release enthält zwei Breaking Changes im SQL-Dialekt: Der Divisionsoperator verwendet standardmäßig Gleitkommadivision, und die Standard-Null-Sortierreihenfolge ändert sich von NULLS FIRST auf NULLS LAST. DuckDB ist noch in der Beta, wir wissen aber, dass viele DuckDB-Abfragen bereits produktiv laufen. Das alte Verhalten lässt sich mit folgenden Einstellungen wiederherstellen:
SET integer_division = true;SET default_null_order = 'NULLS_FIRST';Divisionsoperator. Der Divisionsoperator / führt jetzt auch bei Integer-Parametern immer eine Gleitkommadivision aus. Der neue Operator // behält die alte Semantik und dient der Integer-Division. Damit ist DuckDBs Divisionsoperator für Einsteiger weniger fehleranfällig und konsistent mit der Division in Python 3 und anderen OLAP-Systemen wie Spark, Snowflake und BigQuery.
SELECT 42 / 5, 42 // 5;| (42 / 5) | (42 // 5) |
|---|---|
| 8.4 | 8 |
Standard-Null-Sortierreihenfolge. Die Standard-Null-Sortierreihenfolge ändert sich von NULLS FIRST auf NULLS LAST. Der Grund: NULLS LAST ist zusammen mit LIMIT intuitiver. Mit NULLS FIRST liefern Top-N-Abfragen immer zuerst die NULL-Werte. Mit NULLS LAST kommen stattdessen die tatsächlichen Top-N-Werte.
CREATE TABLE bigdata (col INTEGER);INSERT INTO bigdata VALUES (NULL), (42), (NULL), (43);FROM bigdata ORDER BY col DESC LIMIT 3;| v0.7.1 | v0.8.0 |
|---|---|
| NULL | 43 |
| NULL | 42 |
| 43 | NULL |
Neue SQL-Features
Pivot und Unpivot. Daten kommen in vielen Formen, und den Entstehungsprozess kontrolliert man nicht immer. SQL eignet sich gut zum Umformen von Datensätzen, aber Spalten in Zeilen oder Zeilen in Spalten zu drehen ist in Vanilla-SQL mühsam. Mit diesem Release führt DuckDB die Statements PIVOT und UNPIVOT ein, mit denen sich Datensätze so umformen lassen, dass Zeilen zu Spalten werden oder umgekehrt. Ein Vorteil der DuckDB-Syntax: Die Spaltennamen zum Pivotieren oder Unpivotieren können automatisch ermittelt werden. Ein kurzes Beispiel:
CREATE TABLE sales (year INTEGER, amount INTEGER);INSERT INTO sales VALUES (2021, 42), (2022, 100), (2021, 42);PIVOT sales ON year USING sum(amount);| 2021 | 2022 |
|---|---|
| 84 | 100 |
Die Dokumentation enthält weitere Beispiele.
ASOF-Joins für Zeitreihen. Beim Joinen von Zeitreihendaten mit Fakten-Tabellen passen die Zeitstempel oft nicht exakt. Dann ist es oft erwünscht, so zu joinen, dass der Zeitstempel mit dem nächstgelegenen Zeitstempel verknüpft wird. Der ASOF-Join dient genau dafür – er führt einen Fuzzy-Join aus und findet für jede Zeile den nächsten Join-Partner statt einer exakten Übereinstimmung.
CREATE TABLE a (ts TIMESTAMP);CREATE TABLE b (ts TIMESTAMP);INSERT INTO a VALUES (TIMESTAMP '2023-05-15 10:31:00'), (TIMESTAMP '2023-05-15 11:31:00');INSERT INTO b VALUES (TIMESTAMP '2023-05-15 10:30:00'), (TIMESTAMP '2023-05-15 11:30:00');
FROM a ASOF JOIN b ON a.ts >= b.ts;| a.ts | b.ts |
|---|---|
| 2023-05-15 10:31:00 | 2023-05-15 10:30:00 |
| 2023-05-15 11:31:00 | 2023-05-15 11:30:00 |
Eine ausführlichere Erklärung steht in der Dokumentation.
Verbesserungen der Datenintegration
Paralleler CSV-Reader als Standard. In diesem Release wurde der parallele CSV-Reader stark verbessert und ist jetzt der Standard-CSV-Reader. Wir danken allen, die den experimentellen Reader ausprobiert und wertvolles Feedback gegeben haben. Das Flag experimental_parallel_csv ist veraltet und nicht mehr nötig. Der parallele CSV-Reader ermöglicht deutlich effizienteres Lesen großer CSV-Dateien.
CREATE TABLE lineitem AS FROM lineitem.csv;| v0.7.1 | v0.8.0 |
|---|---|
| 4.1 s | 1.2 s |
Paralleles Schreiben von Parquet, CSV und JSON. Dieses Release unterstützt paralleles reihenfolgeerhaltendes Schreiben von Parquet-, CSV- und JSON-Dateien. Das Schreiben in diese Formate ist damit standardmäßig parallel – auch ohne das Abschalten der Einfügereihenfolge – und deutlich schneller.
COPY lineitem TO 'lineitem.csv';COPY lineitem TO 'lineitem.parquet';COPY lineitem TO 'lineitem.json';| Format | v0.7.1 | v0.8.0 |
|---|---|---|
| CSV | 3.9 s | 0.6 s |
| Parquet | 8.1 s | 1.2 s |
| JSON | 4.4 s | 1.1 s |
Rekursives Datei-Globbing mit **. Dieses Release fügt rekursives Globbing hinzu: Beliebig viele Unterverzeichnisse lassen sich mit dem Operator ** (Doppelstern) treffen.
FROM 'data/glob/crawl/stackoverflow/**/*.csv';Die Dokumentation wurde um verschiedene Beispiele dieser Syntax ergänzt.
Speicherverbesserungen
Lazy-Loading von Tabellenmetadaten. DuckDBs internes Speicherformat legt Metadaten für jede Row Group einer Tabelle ab, etwa Min-Max-Indizes und die Position jeder Row Group in der Datei. Früher lud DuckDB diese Metadaten sofort beim Öffnen der Datenbank. Bei sehr großen Daten können die Metadaten selbst groß werden und den Start merklich verzögern. In diesem Release haben wir die Metadatenbehandlung so optimiert, dass Tabellenmetadaten erst beim Zugriff gelesen werden. Der Start ist damit auch bei großen Datenbanken nahezu sofort, und Metadaten werden nur für Spalten geladen, die in Abfragen tatsächlich vorkommen. Die Benchmarks unten gelten für eine Datenbankdatei mit einer einzelnen großen TPC-H-Tabelle lineitem (120× SF1) mit etwa 770 Millionen Zeilen und 16 Spalten:
| Query | v0.6.1 | v0.7.1 | v0.8.0 | Parquet |
|---|---|---|---|---|
SELECT 42 |
1.60 s | 0.31 s | 0.02 s | - |
FROM lineitem LIMIT 1 |
1.62 s | 0.32 s | 0.03 s | 0.27 s |
Clients
Benutzerdefinierte skalare Funktionen für Python. Beliebige Python-Funktionen können jetzt als skalare Funktionen in SQL-Abfragen registriert werden. Das funktioniert nur, wenn DuckDB aus Python genutzt wird, weil die tatsächliche Python-Laufzeit verwendet wird, in der DuckDB läuft. Es können einfache Python-Werte übergeben werden, es gibt aber auch eine vektorisierte Variante, die intern PyArrow nutzt – effizienter und besser parallelisierbar.
import duckdb
from duckdb.typing import *from faker import Faker
def random_date(): fake = Faker() return fake.date_between()
duckdb.create_function('random_date', random_date, [], DATE)res = duckdb.sql('SELECT random_date()').fetchall()print(res)# [(datetime.date(2019, 5, 15),)]Mehr dazu in der Dokumentation.
Unterstützung für Arrow Database Connectivity (ADBC). ADBC ist ein Datenbank-API-Standard für Zugriffsbibliotheken, der Apache Arrow zum Übertragen von Abfrageergebnissen und zum Einlesen von Daten nutzt. Arrow ist besonders für spaltenorientierte Datenmanagementsysteme vorteilhaft, die bisher durch die Emulation zeilenbasierter APIs wie JDBC/ODBC einen Leistungsnachteil hatten. Ab diesem Release unterstützt DuckDB ADBC nativ. Wir freuen uns, zu den ersten Systemen mit nativer Unterstützung zu gehören; DuckDBs In-Process-Design passt gut zu ADBC.
Swift-Integration. DuckDB hat eine weitere offizielle Sprachintegration: Swift. Swift ist eine von Apple entwickelte Sprache, die vor allem für Apps auf Apple-Geräten genutzt wird, zunehmend aber auch serverseitig. Die DuckDB-Swift-API erlaubt es Entwicklerinnen und Entwicklern auf allen Swift-Plattformen, DuckDB über eine native Swift-Schnittstelle zu nutzen – mit Unterstützung für starke Typisierung und Concurrency.
Schlussbemerkung
Die vollständigen Release Notes finden Sie auf GitHub. Wir danken allen Beitragenden für die Arbeit an DuckDB.