Что такое DuckDB: обзор, сравнение и когда использовать в 2026 году

Обновлено:

DuckDB — встраиваемая аналитическая база данных (OLAP), которая выполняет аналитические запросы прямо внутри вашего приложения или скрипта. Её часто называют «SQLite для аналитики», и сравнение точное: один файл, без сервера и настройки, но оптимизация не под транзакционную запись, а под чтение и агрегацию больших объёмов данных.

Проект вырос в CWI — нидерландском национальном исследовательском институте математики и информатики, написан на C++ и распространяется под лицензией MIT. Сейчас DuckDB — один из стандартных инструментов для аналитики на Python, и его всё чаще встраивают в бэкенды.

OLAP vs OLTP: в чём принципиальное отличие

OLTP (Online Transaction Processing) — транзакционные базы: PostgreSQL, MySQL, SQLite. Оптимизированы для быстрой записи и чтения отдельных строк. Типичный запрос: SELECT * FROM users WHERE id = 12345. Хранение по строкам (row-oriented).

OLAP (Online Analytical Processing) — аналитические базы: DuckDB, ClickHouse, BigQuery, Snowflake. Оптимизированы для запросов, которые читают много строк, но мало колонок, и считают агрегаты. Типичный запрос: SELECT date, SUM(revenue) FROM orders GROUP BY date. Хранение по колонкам (column-oriented).

Почему колоночное хранение быстрее для аналитики? Для SELECT SUM(revenue) FROM orders база читает только колонку revenue, а не все колонки каждой строки. Если в таблице 20 колонок, с диска читается лишь небольшая часть данных. К тому же однотипные значения в колонке хорошо сжимаются.

Как работает DuckDB

Как и SQLite, DuckDB работает как библиотека внутри вашего процесса. Данные хранятся в файле .duckdb или в памяти для временных вычислений.

Установка и первые запросы

# Python
pip install duckdb

# Node.js (официальный клиент)
npm install @duckdb/node-api

# CLI
brew install duckdb        # macOS
winget install DuckDB.cli  # Windows
import duckdb

# Файловая база
con = duckdb.connect('analytics.duckdb')

# Или в памяти
# con = duckdb.connect(':memory:')

con.execute("""
    CREATE TABLE sales (
        date DATE,
        product_id INTEGER,
        category VARCHAR,
        revenue DECIMAL(10,2),
        quantity INTEGER,
        region VARCHAR
    )
""")

# Загрузка из CSV
con.execute("COPY sales FROM 'sales_2026.csv' (FORMAT CSV, HEADER true)")

result = con.execute("""
    SELECT
        date_trunc('month', date) AS month,
        category,
        SUM(revenue) AS total_revenue,
        AVG(revenue) AS avg_revenue,
        COUNT(*) AS order_count
    FROM sales
    WHERE date >= '2026-01-01'
    GROUP BY 1, 2
    ORDER BY 1 DESC, 3 DESC
""").df()  # .df() возвращает pandas DataFrame

print(result)

Запросы к файлам без загрузки

DuckDB выполняет SQL прямо по CSV, Parquet и JSON-файлам:

import duckdb
import pandas as pd

# CSV напрямую
result = duckdb.sql("""
    SELECT region, SUM(revenue) AS total, COUNT(*) AS orders
    FROM read_csv('transactions_2026.csv')
    GROUP BY region
    ORDER BY total DESC
    LIMIT 10
""").df()

# Parquet в S3 (нужен httpfs и секрет с ключами, см. ниже)
result = duckdb.sql("""
    SELECT product_id, SUM(quantity) AS sold
    FROM read_parquet('s3://data-lake/sales/*.parquet')
    WHERE date >= '2026-01-01'
    GROUP BY 1
""").df()

# pandas DataFrame как таблица
df = pd.read_csv('data.csv')
result = duckdb.sql("SELECT * FROM df WHERE revenue > 1000").df()

Параллельное выполнение

DuckDB по умолчанию использует все ядра процессора и обрабатывает данные векторами, а не по одной строке. Поэтому GROUP BY и агрегации по большим таблицам в нём обычно заметно быстрее, чем в строковых OLTP-базах на той же машине. Насколько быстрее — зависит от данных, запроса и железа, так что меряйте на своей задаче.

Производительность: как сравнивать честно

Мы сознательно не приводим таблицу «секунд против секунд»: результаты сильно зависят от версии, железа, формата данных и того, прогрет ли кэш. Если нужны цифры, смотрите открытые воспроизводимые бенчмарки (например, ClickBench) и запускайте их на своём оборудовании. Общая картина устойчива:

  • на сканах, агрегациях и JOIN больших таблиц DuckDB и ClickHouse сильно опережают PostgreSQL и SQLite;
  • на точечных SELECT по ключу и вставке отдельных строк быстрее OLTP-базы;
  • ClickHouse масштабируется на кластер, DuckDB работает на одной машине.

Экосистема расширений

httpfs — чтение файлов по HTTP и из S3:

INSTALL httpfs;
LOAD httpfs;
CREATE SECRET (TYPE s3, KEY_ID 'ключ', SECRET 'секрет', REGION 'ru-central1', ENDPOINT 'storage.yandexcloud.net');
SELECT * FROM read_parquet('s3://bucket/data/*.parquet');

json — работа с JSON:

SELECT json_extract(payload, '$.user.name') FROM events;

spatial — геопространственные функции:

INSTALL spatial;
LOAD spatial;
SELECT ST_Distance(geom1, geom2) FROM places;

iceberg — чтение таблиц Apache Iceberg:

INSTALL iceberg;
LOAD iceberg;
SELECT * FROM iceberg_scan('s3://datalake/iceberg_table/');

MotherDuck — облачный сервис на основе DuckDB. Токен лучше передавать через переменную окружения motherduck_token, а не в строке подключения:

import duckdb
con = duckdb.connect('md:my_database')  # токен из переменной окружения motherduck_token

Когда использовать DuckDB

Подходит для:

  • аналитики и data science: SQL по данным, которые не помещаются в память pandas;
  • ETL-пайплайнов: преобразование CSV, Parquet и JSON без загрузки в серверную БД;
  • подготовки данных для дашбордов и отчётов;
  • локальной аналитики вместо тяжёлых запросов к продакшн-PostgreSQL;
  • аналитики в браузере через DuckDB-Wasm;
  • быстрой проверки логики запросов на локальных данных.

Не подходит для:

  • основного хранилища веб-приложения (берите PostgreSQL или SQLite);
  • интенсивной конкурентной записи: файл может открыть на запись только один процесс;
  • распределённых систем с репликацией (смотрите на ClickHouse);
  • авторизации, сессий и прочих OLTP-задач.

DuckDB vs SQLite vs PostgreSQL vs ClickHouse

| Параметр | DuckDB | SQLite | PostgreSQL | ClickHouse | |---|---|---|---|---| | Класс | OLAP (встраиваемая) | OLTP (встраиваемая) | OLTP (серверная) | OLAP (серверная) | | Хранение | Колоночное | Строковое | Строковое | Колоночное | | Аналитика | ★★★★★ | ★★☆☆☆ | ★★★☆☆ | ★★★★★ | | Транзакции | ★★★☆☆ | ★★★★★ | ★★★★★ | ★☆☆☆☆ | | Встраивание | Да | Да | Нет | Нет | | Нужен сервер | Нет | Нет | Да | Да | | Масштабирование | Одна машина | Одна машина | Вертикальное + реплики | Кластер | | Python | Нативный пакет | Стандартная библиотека | psycopg | clickhouse-connect и др. | | Лицензия | MIT | Public Domain | PostgreSQL License | Apache 2.0 |

Про SQLite подробнее — в статье что такое SQLite.

DuckDB в связке с PostgreSQL

Частый паттерн: PostgreSQL для OLTP, DuckDB для аналитики. Расширение postgres позволяет читать таблицы PostgreSQL прямо из DuckDB:

import duckdb

con = duckdb.connect()
con.execute("INSTALL postgres; LOAD postgres;")

# Лучше подключаться к реплике, а не к основному серверу
con.execute("""
    ATTACH 'postgresql://analyst@replica-host/myapp' AS prod (TYPE POSTGRES, READ_ONLY);
""")

result = con.execute("""
    SELECT
        date_trunc('week', created_at) AS week,
        COUNT(*) AS new_users,
        SUM(COUNT(*)) OVER (ORDER BY date_trunc('week', created_at)) AS cumulative
    FROM prod.users
    GROUP BY 1
    ORDER BY 1
""").df()

Агрегации выполняются в DuckDB, но данные всё равно читаются из PostgreSQL, поэтому направляйте такие запросы на реплику. Пароль держите в ~/.pgpass или переменных окружения, а не в строке подключения.

Бэкап DuckDB-файлов

DuckDB хранит данные в бинарном файле .duckdb, а несброшенные изменения — в файле .duckdb.wal рядом с ним. Копировать файл, пока в него пишет приложение, небезопасно. Варианты:

# 1. Портативный экспорт в Parquet (схема + данные)
duckdb analytics.duckdb -c "EXPORT DATABASE '/tmp/duckdb_export' (FORMAT PARQUET);"

# 2. Согласованная копия в новый файл
duckdb -c "ATTACH '/var/data/analytics.duckdb' AS src (READ_ONLY);
           ATTACH '/tmp/analytics-copy.duckdb' AS dst;
           COPY FROM DATABASE src TO dst;"

# 3. Если приложение остановлено: CHECKPOINT и копия файла
duckdb /var/data/analytics.duckdb -c "CHECKPOINT;"
cp /var/data/analytics.duckdb /tmp/analytics-copy.duckdb

Команды 1 и 2 откроют файл, только если его не держит на запись другой процесс — DuckDB блокирует файл. Поэтому бэкап удобно делать в паузе между загрузками данных или из того же процесса, который пишет в базу. Подробно — в статье бэкап DuckDB.

Готовую копию можно загрузить в dbsend для DuckDB — каждая загрузка станет версией, с таблицами и числом строк, а на платных тарифах — с diff между версиями:

dbsend backup /tmp/analytics-copy.duckdb -d "$DBSEND_DATABASE_ID" -e duckdb -l "duckdb-$(date +%F-%H%M)"

Если рядом с файлом лежит .wal, CLI предупредит, что в копию могут попасть не все изменения. Регулярно проверяйте, что копия открывается и содержит нужные данные: см. как проверить, что бэкап рабочий.

Частые вопросы

Можно ли использовать DuckDB в продакшне?

Да. Стабильная версия 1.0 вышла в 2024 году, с тех пор формат хранения обратно совместим. DuckDB используют в продакшне для аналитических нагрузок: ETL, отчёты, встроенная аналитика. Для транзакционных задач (веб-приложения, авторизация) берите PostgreSQL или SQLite.

В чём разница между DuckDB и pandas?

Оба инструмента для анализа данных, но DuckDB работает через SQL и умеет обрабатывать данные, которые не помещаются в оперативную память, сбрасывая промежуточные результаты на диск. pandas держит весь DataFrame в памяти. Они хорошо дополняют друг друга: DuckDB читает DataFrame как таблицу и возвращает результат как DataFrame.

Чем DuckDB лучше SQLite для аналитики?

Колоночным хранением, векторным и параллельным выполнением запросов. На GROUP BY и SUM по миллионам строк DuckDB обычно значительно быстрее. SQLite с хранением по строкам лучше для точечных запросов и вставки отдельных строк. Простое правило: SQLite — для транзакций, DuckDB — для аналитики.

Работает ли DuckDB в браузере?

Да. DuckDB-Wasm компилируется в WebAssembly и выполняет запросы прямо во фронтенде, без обращения к серверу. Например, на нём построены SQL-ячейки в Observable Framework.

DuckDB бесплатный?

Да, DuckDB распространяется под лицензией MIT. MotherDuck — отдельный коммерческий облачный сервис на основе DuckDB; актуальные тарифы смотрите на его сайте. Для большинства задач хватает локального DuckDB.