DuckDB met Python: De Complete Gids voor Snelle Lokale Data-Analyse in 2026

Leer hoe DuckDB met Python razendsnelle SQL-analyses uitvoert op Pandas, Polars en Parquet-bestanden, inclusief praktische voorbeelden en benchmarks tegen Pandas.

DuckDB Python Snelle Analyse (2026)

Bijgewerkt: 19 juni 2026

DuckDB is een gratis, open-source, in-process analytische SQL-database die specifiek is ontworpen voor snelle data-analyse op een enkele machine. In tegenstelling tot SQLite, dat geoptimaliseerd is voor transactionele werklasten, gebruikt DuckDB een kolom-georiënteerde vectorized engine die ideaal is voor analytische queries op Pandas-DataFrames, Polars-DataFrames en Parquet-bestanden. In deze gids leer je hoe je DuckDB installeert in Python, queries uitvoert op bestaande data, en je analyse-workflows tot tien keer sneller maakt dan traditionele Pandas-pipelines.

  • DuckDB 1.3 draait volledig in-process binnen je Python-proces, dus geen server en geen aparte database-engine te installeren.
  • Je kunt direct SQL uitvoeren op bestaande Pandas- en Polars-DataFrames zonder data te kopiëren dankzij zero-copy integratie.
  • DuckDB leest Parquet-, CSV- en JSON-bestanden lokaal én via HTTPS/S3 met de httpfs-extensie.
  • Voor analytische queries op datasets groter dan het RAM-geheugen spillt DuckDB automatisch naar schijf.
  • Benchmarks tonen 5 tot 10x snelheidswinst ten opzichte van Pandas bij groupby- en join-operaties op datasets boven 1 GB.
  • DuckDB is geschreven in C++ en biedt officiële Python-bindings via het pakket duckdb op PyPI.

Wat is DuckDB en waarom gebruiken?

DuckDB combineert het beste van twee werelden: de eenvoud van SQLite (één bestand, geen server, embedded in je applicatie) en de prestaties van moderne analytische engines zoals ClickHouse of Snowflake. De engine gebruikt vectorized query execution, kolomopslag en parallelle uitvoering op meerdere CPU-cores. Eigenschappen die normaal alleen in dure datawarehouses voorkomen.

De typische use-cases waarin DuckDB uitblinkt zijn explorerende data-analyse op laptopformaat, ETL-stappen in een Python-script, lokale ad-hocrapportages en het transformeren van Parquet-bestanden voordat ze naar een datalake gaan. Wanneer je workflow vooral bestaat uit lezen, aggregeren en joinen (dus geen hoge volumes inserts of updates), is DuckDB vrijwel altijd sneller dan Pandas en eenvoudiger te onderhouden dan een externe database.

Eerlijk gezegd was dit voor mij de grootste verrassing toen ik vorig kwartaal een 40 GB Parquet-set analyseerde op een MacBook met 16 GB RAM: wat in Pandas vastliep, was in DuckDB binnen een minuut klaar.

Bovendien houdt DuckDB jouw bestaande Python-data dichtbij. Je kunt een query starten op een Pandas-DataFrame, het resultaat in Polars laden en doorzetten naar Matplotlib, allemaal binnen één Python-script. Voor wie eerder vergeleek welke library snelheidsvoordeel biedt, raad ik aan om eerst onze gids Polars vs Pandas voor snellere data-analyse te lezen. DuckDB werkt met beide.

DuckDB installeren in Python

Het installeren van DuckDB in Python kost één regel. De officiële bindings staan op PyPI en ondersteunen Python 3.9 tot en met 3.13, inclusief wheels voor Linux, macOS (Apple Silicon en Intel) en Windows. Vanaf versie 1.3 worden ook ARM Linux-wheels meegeleverd, wat installatie op Raspberry Pi en cloud-VMs eenvoudig maakt.

# Basisinstallatie
pip install duckdb

# Aanbevolen: ook Pandas en Polars voor integratie
pip install duckdb pandas polars pyarrow

Verifieer de installatie en bekijk de versie met de volgende REPL-opdracht. DuckDB versie 1.3 (uitgebracht in mei 2025) bracht onder andere snellere CSV-parsing en uitbreidingen aan de variant-typen.

import duckdb

print(duckdb.__version__)        # bv. '1.3.0'
print(duckdb.sql("SELECT 42 AS antwoord").fetchall())
# [(42,)]

SQL uitvoeren op Pandas-DataFrames

De krachtigste eigenschap van DuckDB in een Python-context is dat je SQL kunt schrijven direct op je bestaande Pandas-DataFrames zonder eerst data in te laden of te kopiëren. DuckDB herkent variabelen in de lokale namespace en behandelt ze als tabellen (een feature die "replacement scans" heet en intern gebruikmaakt van Apache Arrow voor zero-copy data-overdracht).

import duckdb
import pandas as pd

# Voorbeelddata: verkoop per regio
verkoop = pd.DataFrame({
    "regio": ["Noord", "Zuid", "Oost", "West", "Noord", "Zuid"],
    "product": ["A", "A", "B", "B", "B", "A"],
    "omzet": [1200, 800, 1500, 900, 2200, 1100],
})

# SQL direct op het DataFrame
resultaat = duckdb.sql("""
    SELECT regio,
           SUM(omzet) AS totaal_omzet,
           COUNT(*) AS aantal_verkopen
    FROM verkoop
    GROUP BY regio
    ORDER BY totaal_omzet DESC
""").df()

print(resultaat)

De methode .df() converteert het queryresultaat terug naar een Pandas-DataFrame. Wil je Polars in plaats van Pandas, gebruik dan .pl(); voor een PyArrow Table is dat .arrow(). Deze flexibiliteit maakt DuckDB ideaal als analytische lijm tussen verschillende dataformaten.

Parquet- en CSV-bestanden direct lezen

DuckDB kan Parquet-, CSV- en JSON-bestanden bevragen alsof het tabellen zijn, zonder ze eerst expliciet in te laden. Dit is bijzonder krachtig bij grote bestanden omdat DuckDB alleen de relevante kolommen en rijgroepen leest (predicate pushdown). Een query op een kolom van een Parquet-bestand van 5 GB kan in milliseconden klaar zijn als de filter selectief genoeg is.

import duckdb

# Direct query op een Parquet-bestand
top_klanten = duckdb.sql("""
    SELECT klant_id, SUM(bedrag) AS totaal
    FROM 'data/transacties_2026.parquet'
    WHERE land = 'NL'
    GROUP BY klant_id
    ORDER BY totaal DESC
    LIMIT 10
""").df()

# Glob-patronen werken ook
maand_overzicht = duckdb.sql("""
    SELECT DATE_TRUNC('month', datum) AS maand,
           SUM(omzet) AS omzet
    FROM 'data/2026/*.parquet'
    GROUP BY maand
    ORDER BY maand
""").df()

Voor CSV-bestanden detecteert DuckDB automatisch het scheidingsteken, kolomtypes en aanwezigheid van een header. De parser is in versie 1.3 verder versneld en behandelt nu ook ongebruikelijke quoting-stijlen correct. In mijn laatste project bespaarde dit me een halve dag aan handmatig kolommen typeren. Voor diepgaande tips over het opschonen van ruwe data raad ik ons artikel data opschonen met Pandas 3.0 aan; DuckDB en Pandas vullen elkaar prima aan.

Volgens de officiële DuckDB Parquet-documentatie ondersteunt de engine ook gepartitioneerde directorystructuren (Hive-partitioning), wat handig is voor grote datalakes.

Is DuckDB sneller dan Pandas?

In de meeste analytische workloads is DuckDB sneller dan Pandas. Vaak 5 tot 10 keer sneller bij groupby-, join- en filteroperaties op datasets boven enkele honderden megabytes. Dit komt door de vectorized execution engine, het kolomopslagformaat (intern gebaseerd op Apache Arrow) en automatische parallelisatie over alle beschikbare CPU-cores. Pandas daarentegen draait standaard single-threaded en gebruikt rij-georiënteerde structuren.

EigenschapDuckDB 1.3Pandas 2.x
Query-taalStandaard SQLPython DataFrame API
EngineVectorized, kolom-georiënteerdRij-georiënteerd (NumPy/Arrow)
ParallelisatieMulti-threaded standaardSingle-threaded standaard
Geheugen overschrijdenSpillt automatisch naar schijfMemoryError boven RAM
Parquet/CSV lezenDirect via SQL, met predicate pushdownVolledige inlading via read_parquet
Typische groupby-snelheid~5 tot 10x sneller op >1 GBReferentiewaarde
LeercurveSQL-kennis vereistPython-only

Belangrijke nuance: voor kleine datasets onder 100 MB is het verschil verwaarloosbaar en wint Pandas soms door minder overhead bij het starten van queries. Ook bij workflows die intensieve elementgewijze transformaties uitvoeren (bijvoorbeeld string-bewerkingen of complexe lambda-functies) blijft Pandas competitief. DuckDB excelleert vooral bij analytische SQL-patronen.

DuckDB combineren met Polars

DuckDB en Polars zijn geen concurrenten, ze vullen elkaar juist uitstekend aan. Polars is een snelle DataFrame-bibliotheek met een Pythonische API, terwijl DuckDB SQL biedt en uitblinkt in joins en aggregaties. Beide gebruiken Arrow als geheugenformaat, wat zero-copy uitwisseling mogelijk maakt.

import duckdb
import polars as pl

orders = pl.read_parquet("orders.parquet")
klanten = pl.read_parquet("klanten.parquet")

# SQL-join uitvoeren op twee Polars-DataFrames
verrijkt = duckdb.sql("""
    SELECT o.order_id,
           o.datum,
           o.bedrag,
           k.land,
           k.segment
    FROM orders o
    JOIN klanten k USING (klant_id)
    WHERE o.datum >= DATE '2026-01-01'
""").pl()

print(type(verrijkt))   # polars.DataFrame

Dit patroon is bijzonder handig: laad ruwe data met Polars (vaak iets sneller voor I/O), doe complexe transformaties in SQL via DuckDB en zet het eindresultaat terug naar Polars voor verdere bewerking of plotting. De overhead tussen beide engines is minimaal omdat ze hetzelfde Arrow-geheugenformaat delen.

Window-functies en geavanceerde aggregaties

DuckDB ondersteunt het volledige SQL-standaard repertoire aan window-functies, inclusief ROW_NUMBER(), RANK(), LAG(), LEAD() en aangepaste vensters met RANGE- en ROWS-clausules. Voor analyses zoals voortschrijdende gemiddelden, ranking binnen groepen of cohortanalyses is dit veel beknopter dan equivalente Pandas-code met rolling of expanding.

import duckdb

verkopen = duckdb.sql("""
    SELECT product,
           datum,
           omzet,
           SUM(omzet) OVER (
               PARTITION BY product
               ORDER BY datum
               ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
           ) AS rolling_7d_omzet,
           RANK() OVER (
               PARTITION BY DATE_TRUNC('month', datum)
               ORDER BY omzet DESC
           ) AS rang_in_maand
    FROM 'verkoop_2026.parquet'
""").df()

Voor tijdreeksanalyses combineert DuckDB uitstekend met statistische bibliotheken. Zie ook onze gids tijdreeksanalyse met Python (Pandas tot Prophet) voor voorbeelden waarin SQL-aggregaties als feature-input dienen voor voorspellingsmodellen.

Werken met datasets groter dan RAM

Een van de meest onderscheidende eigenschappen van DuckDB is de mogelijkheid om datasets te verwerken die groter zijn dan het beschikbare werkgeheugen. Wanneer een query meer geheugen nodig heeft dan beschikbaar is, spillt DuckDB tussenresultaten automatisch naar een tijdelijke schijflocatie. Dit betekent dat je op een laptop met 16 GB RAM zonder problemen Parquet-bestanden van 50 GB kunt analyseren, iets wat met Pandas vrijwel onmogelijk is zonder chunking.

import duckdb

# Verbind met een persistent bestand voor caching en grote queries
con = duckdb.connect("analyse.duckdb")

# Stel een geheugenlimiet en tijdelijke directory in
con.execute("SET memory_limit = '8GB'")
con.execute("SET temp_directory = '/tmp/duckdb_spill'")

# Query op een Parquet-bestand van tientallen GB
resultaat = con.execute("""
    SELECT land,
           AVG(bedrag) AS gemiddelde,
           COUNT(*) AS transacties
    FROM 'transacties_volledig.parquet'
    GROUP BY land
    HAVING COUNT(*) > 1000
""").fetch_df()

Nuttige DuckDB-extensies

DuckDB heeft een uitbreidbaar extensiesysteem dat extra functionaliteit toevoegt zonder de kerngrootte op te blazen. Drie extensies die elke data-engineer zou moeten kennen zijn httpfs voor cloudtoegang, spatial voor geografische analyses en json voor het bevragen van geneste JSON-structuren. Extensies worden eenmalig geïnstalleerd en daarna automatisch geladen.

import duckdb

con = duckdb.connect()

# Cloudbestanden lezen via httpfs
con.execute("INSTALL httpfs; LOAD httpfs;")
con.execute("SET s3_region='eu-west-1';")

remote_df = con.execute("""
    SELECT * FROM 's3://mijn-bucket/data/2026/maart.parquet'
    LIMIT 1000
""").fetch_df()

# Geografische queries
con.execute("INSTALL spatial; LOAD spatial;")
afstand = con.execute("""
    SELECT ST_Distance(
        ST_Point(4.9041, 52.3676),   -- Amsterdam
        ST_Point(4.4777, 51.9244)    -- Rotterdam
    ) AS km_globe
""").fetchone()

Een volledige lijst staat in het DuckDB extensies-overzicht. De repository op GitHub bevat ook actuele release notes en een actieve community-discussie waar nieuwe features eerst opduiken.

Veelgestelde vragen

Kan DuckDB SQLite vervangen?

Niet voor elk doel. DuckDB is geoptimaliseerd voor analytische queries (OLAP), terwijl SQLite uitblinkt in transactionele workloads (OLTP) met veel kleine inserts en updates. Voor read-heavy analytics is DuckDB de betere keuze; voor een applicatiedatabase blijft SQLite passender.

Hoe groot mag een DuckDB-bestand zijn?

Technisch geldt er geen harde limiet. Bestanden van tientallen tot honderden GB komen regelmatig voor in productie. De praktische grens wordt bepaald door je schijfruimte en query-complexiteit, niet door de engine zelf.

Werkt DuckDB met Jupyter Notebook?

Ja, DuckDB is uitstekend geschikt voor Jupyter. Je kunt resultaten direct als Pandas- of Polars-DataFrame terugkrijgen, en met de jupysql-magic schrijf je SQL in een cel met %%sql. Voor exploratieve analyse is dit een zeer productieve combinatie.

Heeft DuckDB een GUI?

Officieel is DuckDB een commandline- en library-tool, maar er zijn meerdere GUIs van derden zoals DBeaver, Tad en de webgebaseerde DuckDB UI (sinds versie 1.3 meegeleverd). Voor productieanalyse blijft Python plus Jupyter de meest gebruikte interface.

Is DuckDB gratis voor commercieel gebruik?

Ja. DuckDB is uitgebracht onder de MIT-licentie en is volledig gratis voor zowel persoonlijk als commercieel gebruik, inclusief integratie in gesloten-bron-software. Er zijn geen abonnementen of cloudafhankelijkheden vereist.

Editorial Team
Over de Auteur Editorial Team

Our team of expert writers and editors.