В мире обработки данных, где доминируют тяжеловесные клиент-серверные СУБД, DuckDB появляется как свежий ветер. Это встраиваемая аналитическая СУБД, созданная для скорости выполнения сложных запросов прямо на месте, без необходимости развертывания отдельного сервера. Ее сравнивают с SQLite для аналитики. Но как понять, что она подходит именно для вашего проекта? Давайте разберем ключевые критерии выбора и проиллюстрируем их живыми примерами кода.
Первый и главный вопрос: ваш сценарий использования. DuckDB блестяще справляется с задачами аналитической обработки данных (OLAP) на одном узле. Если вам нужно выполнять агрегации, оконные функции, соединения больших таблиц прямо из файлов (Parquet, CSV) или из памяти pandas DataFrame — это ваш выбор. Например, для интерактивного анализа логов, трансформации данных в ETL-пайплайнах или как движок запросов внутри приложения. Однако для высоконагруженных транзакционных систем (OLTP) с тысячами параллельных запросов на запись стоит смотреть в сторону традиционных серверных СУБД.
Рассмотрим простейший пример установки и начала работы. DuckDB не требует сервера, это библиотека.
Установка через pip: pip install duckdb
Пример кода на Python для чтения CSV и выполнения запроса:
import duckdb
Создаем соединение. Если файла нет, он будет создан.
conn = duckdb.connect('my_database.db')
Читаем CSV-файл напрямую в таблицу (виртуальную)
result = conn.execute("""
SELECT department, AVG(salary) as avg_salary
FROM read_csv_auto('employees.csv')
GROUP BY department
ORDER BY avg_salary DESC
""").fetchall()
print(result)
Мы даже не создавали таблицу в базе! Функция read_csv_auto автоматически определяет схему.
Одной из killer-фич DuckDB является его беспрецедентная работа с форматом Parquet. Он может запрашивать отдельные столбцы и строки из файлов, что идеально для работы с данными в data lake. Пример:
Анализируем сразу несколько паркет-файлов, как если бы это была одна таблица
query = """
SELECT year, category, SUM(revenue) as total_rev
FROM read_parquet('sales/*.parquet')
WHERE year >= 2023
GROUP BY year, category
"""
result = conn.execute(query).df() Возвращаем результат как pandas DataFrame
Важный критерий выбора — интеграция с экосистемой. DuckDB имеет отличные коннекторы для Python, R, Java, C/C++, а также может работать как движок SQL для инструментов вроде Metabase или Apache Superset (через ODBC). Для Data Scientists интеграция с pandas выглядит магически:
import pandas as pd
import duckdb
df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': ['foo', 'bar', 'foo', 'bar']})
Запрос к DataFrame напрямую, без экспорта
duckdb.sql("SELECT b, AVG(a) FROM df GROUP BY b").show()
Или даже запрос к нескольким DataFrame и файлам одновременно
df2 = pd.DataFrame({'b': ['foo', 'bar'], 'category': ['X', 'Y']})
result = duckdb.sql("""
SELECT df.b, df2.category, SUM(df.a)
FROM df JOIN df2 ON df.b = df2.b
GROUP BY df.b, df2.category
""").to_df()
Производительность — следующее соображение. DuckDB использует векторный columnar-движок исполнения запросов, что дает огромный выигрыш в аналитических workloads. Он эффективно использует кэши процессора и SIMD-инструкции. Однако, для достижения максимума, данные лучше загрузить в нативное для DuckDB хранилище, а не запрашивать каждый раз из файлов. Сравним:
Вариант 1: Запрос к CSV каждый раз (медленнее для повторных запросов)
conn.execute("CREATE VIEW sales_view AS SELECT * FROM read_csv_auto('big_sales.csv')")
Вариант 2: Загрузка в постоянную таблицу (быстрее для анализа)
conn.execute("CREATE TABLE sales AS SELECT * FROM read_csv_auto('big_sales.csv')")
После этого запросы к таблице sales будут выполняться на порядок быстрее.
Выбор также зависит от объема данных. DuckDB отлично работает на datasets, которые помещаются на диск одного сервера (от гигабайт до нескольких терабайт). Он не является распределенной системой, как ClickHouse или Spark. Но его способность "заглядывать" в внешние файлы делает его идеальным кандидатом для предварительного анализа больших данных перед их загрузкой в более тяжелые системы.
Не стоит забывать про расширяемость. DuckDB поддерживает пользовательские скалярные и агрегатные функции, написанные на Python или C++. Это открывает двери для кастомной логики.
Пример создания скалярной функции на Python:
def reverse_string(s: str) -> str:
return s[::-1]
conn.create_function('reverse', reverse_string)
conn.execute("SELECT reverse('Hello DuckDB')").fetchone() Вернет ('BDkcuD olleH',)
В заключение, выбирайте DuckDB, если вам нужна легковесная, но мощная аналитическая СУБД "в процессе", для интерактивного анализа, ETL-задач или как встроенного движка в ваше приложение. Начните с запросов к вашим CSV/Parquet файлам, и вы быстро поймете, насколько эта технология может упростить ваш data workflow.
Как выбрать DuckDB: практическое руководство с примерами кода для аналитиков и разработчиков
Подробное руководство по выбору встраиваемой аналитической СУБД DuckDB для различных сценариев работы с данными. Статья содержит практические примеры кода на Python, демонстрирующие интеграцию с CSV, Parquet и pandas, а также критерии оценки применимости технологии в проекте.
491
5
Комментарии (9)