← На главную

DuckDB пришёл в Clojure через TMD: join 50GB CSV за 2.5 сек

04.08.2026 22:09 · hackernews

DuckDB теперь можно использовать из Clojure через tech.ml.dataset (TMD). TMD — это in-memory колоночная платформа для обработки данных. Когда данные не влезают в память, приходится работать с выборками или фильтровать подмножества. Для персистентности используют nippy, arrow или parquet. Но на файлах порядка 100GB с реляционной структурой такие инструменты становятся неудобными, а ввязываться в кластерные разборки не хочется. Реляционные БД хорошо хранят данные и быстро выполняют запросы, однако через JDBC и Postgres данные приходится перегонять из строк в колонки неэффективным небатчевым API.

DuckDB появился через github issue в мае 2021 года, а к декабрю интеграцию tmducken уже подключили через C bindings. Тогда результаты запросов возвращались целиком и должны были помещаться в память, к тому же не было быстрой вставки. С тех пор C interface научился работать батчами на вставку и чтение. Это позволяет обрабатывать очень большие join. Теперь через TMD из Clojure можно обращаться к векторизованному SQL-движку DuckDB.

В примере берут 50GB CSV с 400 000 000 строк. Загрузка в DuckDB занимает 1 минуту 50 секунд, файл сжимается до 18GB вместе со всеми автоматическими индексами. COUNT(*) через Clojure отвечает за 10 миллисекунд. Затем создают таблицу colors: 35 179 строк, у каждого sku примерно 3.51 цвета. Join этих данных с 400M транзакций даёт 1 416 737 859 строк на ноутбуке за 2.5 секунды. Запрос «сколько товаров каждого цвета продано в марте 2021» выполняется за секунду.

Для задач, которые не выражаются в SQL, можно через TMD редуцировать по всем транзакциям конкретного sku. Это тоже занимает около секунды. DuckDB поддерживает zero copy query pathway: если результат не выходит за пределы редьюса, через опцию {:reduce-type :zero-copy-imm} включается самый экономный путь по памяти.

Ещё детали. DuckDB сам строит minmax-индексы, они же BRIN. Для уникальных и первичных ключей автоматически создаёт ART-индексы. Для категорийных колонок индексы можно добавить вручную, но это увеличит размер базы и замедлит транзакции. Код написан на C++11, легко портируется, под mac m-1 вариант собрали быстро. В src около 100 000 строк C++. Проект распространяется под MIT, разработка открытая, комьюнити быстро отвечает. DuckDB хорошо дополняет TMD и позволяет небольшой команде обрабатывать большие данные на ноутбуке, не подключая дорогие распределённые системы.

Читать оригинал →