Что такое DuckDB: встраиваемая OLAP-база данных для аналитики
DuckDB — это встраиваемая аналитическая база данных (OLAP), созданная для быстрого выполнения аналитических запросов непосредственно внутри вашего приложения или скрипта. Её часто называют «SQLite для аналитики», и это точная характеристика: один файл, без сервера, без настройки — но оптимизированная не для транзакционной записи, а для чтения и агрегации больших объёмов данных.
Проект создан в 2019 году в Центре математики и информатики Нидерландов (CWI), написан на C++. В 2026 году DuckDB стал стандартным инструментом для data science и аналитики на Python — и активно проникает в backend-разработку.
OLAP vs OLTP: в чём принципиальное отличие
Чтобы понять DuckDB, нужно понять разницу между двумя классами баз данных:
OLTP (Online Transaction Processing) — транзакционные базы: PostgreSQL, MySQL, SQLite. Оптимизированы для быстрой записи и чтения отдельных строк. Типичный запрос: SELECT * FROM users WHERE id = 12345. Строковое хранение данных (row-oriented storage).
OLAP (Online Analytical Processing) — аналитические базы: DuckDB, ClickHouse, BigQuery, Snowflake. Оптимизированы для запросов, которые читают много строк, но мало столбцов и считают агрегаты. Типичный запрос: SELECT date, SUM(revenue) FROM orders GROUP BY date. Колончатое хранение данных (column-oriented storage).
Почему колончатое хранение быстрее для аналитики? При запросе SELECT SUM(revenue) FROM orders база данных читает только один столбец (revenue), а не все столбцы каждой строки. На таблице в 100 миллионов строк и 20 колонках это разница в 20x по объёму чтения с диска.
Как работает DuckDB
DuckDB — встраиваемая база. Как SQLite, она работает как библиотека внутри вашего процесса без отдельного сервера. Данные хранятся в файле .duckdb или в памяти для временных вычислений.
Установка и первые запросы
# Python
pip install duckdb
# Node.js
npm install duckdb-async
# 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: запросы к файлам без загрузки
DuckDB умеет выполнять SQL-запросы напрямую к CSV, Parquet и JSON файлам — без предварительной загрузки в базу данных:
import duckdb
# Запрос к 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 (data lake)
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
import pandas as pd
df = pd.read_csv('data.csv')
# DuckDB регистрирует DataFrame как виртуальную таблицу
result = duckdb.sql("SELECT * FROM df WHERE revenue > 1000").df()
Параллельное выполнение запросов
DuckDB автоматически использует все ядра процессора. На 10-ядерной машине GROUP BY по 100 миллионам строк выполняется параллельно — в 8-10 раз быстрее, чем однопоточный PostgreSQL.
# DuckDB автоматически параллелизирует этот запрос
result = duckdb.sql("""
SELECT
user_id,
COUNT(*) as events,
COUNT(DISTINCT session_id) as sessions
FROM events_table -- 500 миллионов строк
GROUP BY user_id
""").df()
# На 8-ядерной машине: ~3-5 секунд вместо 40-60 секунд в PostgreSQL
Реальные бенчмарки: DuckDB vs конкуренты
По данным ai2sql.io (март 2026), на таблице 10 миллионов строк:
| Операция | DuckDB | PostgreSQL | SQLite | ClickHouse | |---|---|---|---|---| | Full table scan + GROUP BY | 0.4 сек | 8.2 сек | 12.1 сек | 0.2 сек | | JOIN двух таблиц (100M + 1M строк) | 2.1 сек | 18.4 сек | OOM | 0.9 сек | | Агрегация с окном (window function) | 1.2 сек | 6.8 сек | 9.4 сек | 0.6 сек | | Точечный SELECT по id | 0.8 мс | 0.1 мс | 0.08 мс | 1.2 мс | | INSERT одной строки | 2.1 мс | 0.3 мс | 0.4 мс | 15 мс |
Вывод: DuckDB на аналитических запросах быстрее PostgreSQL в 5-20 раз. На точечных транзакционных операциях PostgreSQL и SQLite значительно быстрее. ClickHouse быстрее DuckDB на огромных кластерах, но требует отдельного сервера.
Экосистема DuckDB в 2026 году
DuckDB обзавёлся богатой экосистемой расширений:
httpfs — запросы к файлам через HTTP и S3 без скачивания:
INSTALL httpfs;
LOAD httpfs;
SELECT * FROM read_parquet('s3://bucket/data/*.parquet');
json — нативная работа с JSON:
SELECT json_extract(payload, '$.user.name') FROM events;
spatial — геопространственные запросы (аналог PostGIS):
INSTALL spatial;
LOAD spatial;
SELECT ST_Distance(geom1, geom2) FROM places;
iceberg — работа с Apache Iceberg таблицами (data lakehouse):
SELECT * FROM iceberg_scan('s3://datalake/iceberg_table/');
MotherDuck — управляемый облачный DuckDB с шарингом запросов:
import duckdb
con = duckdb.connect('md:my_database?motherduck_token=...')
Когда использовать DuckDB
Используйте DuckDB для:
- Аналитики и data science: быстрее pandas для больших датасетов, мощнее SQLite
- ETL-пайплайнов: трансформация CSV, Parquet, JSON без загрузки в БД
- Дашбордов и отчётов: агрегация данных перед отдачей в BI-инструменты
- Локальной обработки данных: вместо создания запроса к продакшн PostgreSQL
- WASM в браузере: DuckDB работает в WebAssembly — аналитика прямо во фронтенде
- Тестирования запросов: быстрая проверка логики на локальных данных
Не используйте DuckDB для:
- Основного хранилища web-приложения (нужен PostgreSQL или SQLite)
- Высококонкурентной записи (DuckDB не оптимизирован для OLTP)
- Реплицированных, распределённых систем (используйте ClickHouse)
- Авторизации, сессий, транзакционных операций
DuckDB vs SQLite vs PostgreSQL vs ClickHouse
| Параметр | DuckDB | SQLite | PostgreSQL | ClickHouse | |---|---|---|---|---| | Класс | OLAP (встраиваемая) | OLTP (встраиваемая) | OLTP (серверная) | OLAP (серверная) | | Хранение | Колончатое | Строковое | Строковое | Колончатое | | Аналитика | ★★★★★ | ★★☆☆☆ | ★★★☆☆ | ★★★★★ | | Транзакции | ★★☆☆☆ | ★★★★★ | ★★★★★ | ★☆☆☆☆ | | Встраивание | Да | Да | Нет | Нет | | Сервер нужен | Нет | Нет | Да | Да | | Масштабирование | Один узел | Один узел | Вертикальное | Кластер | | Python-интеграция | Нативная | Хорошая | Через psycopg | Через clickhouse-driver | | Лицензия | MIT | Public Domain | PostgreSQL | Apache 2.0 |
DuckDB в связке с PostgreSQL: лучший из двух миров
Распространённый паттерн в 2026 году: PostgreSQL для OLTP + DuckDB для аналитики. Данные хранятся в PostgreSQL, аналитические запросы выполняются через DuckDB:
import duckdb
import psycopg2
# Подключаем DuckDB к PostgreSQL через расширение postgres
con = duckdb.connect()
con.execute("INSTALL postgres; LOAD postgres;")
# Читаем данные из PostgreSQL для аналитики
con.execute("""
ATTACH 'postgresql://user:pass@prod-host/myapp' AS prod (TYPE POSTGRES, READ_ONLY);
""")
# Выполняем аналитический запрос на данных PostgreSQL с DuckDB-скоростью
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()
Это позволяет не нагружать продакшн PostgreSQL тяжёлыми аналитическими запросами — DuckDB читает данные с реплики и выполняет агрегации локально.
Бэкап DuckDB-файлов
DuckDB хранит данные в бинарном файле .duckdb. Бэкап через dbsend.ru:
# Экспорт DuckDB в Parquet (портативный формат)
duckdb analytics.duckdb -c "EXPORT DATABASE '/tmp/duckdb_export' (FORMAT PARQUET);"
# Бэкап через dbsend.ru
dbsend backup \
--path=/var/data/analytics.duckdb \
--destination=s3://my-bucket/duckdb \
--schedule=daily
# Или экспорт перед бэкапом
dbsend backup \
--pre-command="duckdb /var/data/analytics.duckdb -c \"CHECKPOINT;\"" \
--path=/var/data/analytics.duckdb \
--destination=s3://my-bucket/duckdb \
--schedule=daily
FAQ
Можно ли использовать DuckDB в продакшне?
Да, DuckDB 1.0 вышел в 2024 году и активно используется в production для аналитических рабочих нагрузок. MotherDuck предоставляет managed DuckDB с высокой доступностью. Для транзакционных нагрузок (web-приложения, авторизация) используйте PostgreSQL или SQLite — DuckDB для этого не предназначен.
В чём разница между DuckDB и pandas?
Оба инструмента предназначены для аналитики данных, но DuckDB работает через SQL и оптимизирован для больших датасетов, не умещающихся в памяти. pandas загружает всё в RAM — на датасете в 10 GB он падает с OOM, DuckDB справляется. DuckDB и pandas хорошо интегрируются: DuckDB может читать pandas DataFrame и возвращать результаты как DataFrame.
Чем DuckDB лучше SQLite для аналитики?
DuckDB использует колончатое хранение и параллельное выполнение — на аналитических запросах оно быстрее SQLite в 10-30 раз. SQLite строковое хранение эффективно для OLTP (точечные запросы, вставка строк), но медленно для GROUP BY и SUM по миллионам строк. Выбирайте: SQLite для транзакций, DuckDB для аналитики.
Работает ли DuckDB в браузере?
Да. DuckDB компилируется в WebAssembly и работает в браузере. Это открывает возможность выполнять аналитику данных прямо во фронтенде без обращения к серверу. Используется в Observable Framework, Jupyter Lite и других инструментах для data science в браузере.
DuckDB бесплатный?
DuckDB — полностью открытый (MIT licence) и бесплатный. MotherDuck — managed облачный DuckDB, платный (от $30/мес), предоставляет GUI, шаринг данных и интеграции. Для большинства задач локального DuckDB достаточно.