Осенью 2026 года выйдет DuckDB v2.0, и в нём появится асинхронное чтение Parquet и CSV. Раньше DuckDB читал файлы синхронно, и при работе с удалённым хранилищем рабочий поток блокировался в ожидании данных. На типичной связке S3 + EC2 это приводило к тому, что машина простаивала: запросов в полёте слишком мало, чтобы занять доступную сеть.
В DuckDB теперь два отдельных пула потоков. REGULAR — обычные рабочие потоки, по одному на ядро CPU, они занимаются декодированием, join'ами, агрегациями. ASYNC — пул для блокирующего I/O, по умолчанию в четыре раза больше системных потоков, но не более 256. ASYNC-потоки держат fetch tasks в полёте заранее, с опережением, чтобы скрыть задержку удалённого хранилища. Это называется read-ahead. Чтобы предвыборка не съела всю память, добавили опцию read_ahead_depth: -1 — без лимита глубины, но с бюджетом через менеджер временной памяти; N > 0 — не больше N задач в очереди; 0 — выключить.
На TPC-H Query 6 при SF100, когда данные лежат на S3, время выполнения упало с 8.230 секунд в DuckDB v1.5.5 до 2.844 секунд в v2.0.0-dev — почти в три раза. С ручной настройкой (async_threads = 48, http_retries = 8 и так далее) получили 2.227 секунды, это уже в 3.7 раза быстрее. Сеть 25 Gbit/s при этом почти полностью загружена, тогда как v1.5.5 упирается примерно в 5 Gbit/s. На холодном локальном чтении с SSD тоже быстрее: 1.321 → 0.883 секунды, примерно в полтора раза. На партиционированном датасете из 976 файлов — 9.344 → 2.945 секунды.
Размер row groups сильно влияет на результат. На машине с 64 vCPU быстрее всего оказалось 306 row groups (2.11 секунды), а один огромный row group дал 25.26 секунды — параллелизма не хватает, чтобы насытить сеть. При одновременном запуске четырёх запросов TPC-H v1.5.5 в среднем использовал 5.9 из 64 ядер, а v2.0.0-dev — 48 ядер, и время выполнения упало с 35.8 до 15.6 секунды. Даже с ограничением памяти в 8 GB асинхронная версия остаётся значительно быстрее.
Особенно эффект заметен на CSV: файл на 80.89 GB читался 877 секунд, а с асинхронным I/O — 45 секунд, почти в 20 раз быстрее. Дальше разработчики планируют добавить асинхронное чтение для JSON и DuckDB-native формата, а также присматриваются к io_uring. Попробовать асинхронный I/O можно уже в preview-сборках v2.0.0-dev.