
2026/10/11 3:08
DuckDB 2.0 が速い理由とは
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
DuckDB 2.0 alpha は、非同期 I/O、改良された再帰的 CTE エンジン、そして新しい VARIANT データ型の 3 つの中核的な進展を通じて、大幅なパフォーマンスと効率性の向上を達成しています。非同期 I/O は、ネットワーク処理と CPU タスクを同時に行うために別個のダウンロードスレッドプールを利用し、DuckDB 1.5.5 で必要だった AWS S3 クエリ時間の 18.8 秒から、2.0 alpha では 7.7 秒へ短縮しました。レガシーな動作が必要なユーザー向けに、
read_ahead_depth を 0 に設定することでアイドル時のダウンロード/デコードを復元できます。再帰的 CTE エンジンでは、テーブルを一度だけ読み込みながら内部の親参照を検索するため、Git履歴のトラバースなど深い階層構造においては最大 40 倍のパフォーマンス向上(約 16 秒から 0.1 秒へ)を実現しますが、浅い構造においては改善は僅かです。新しい VARIANT タイプは、一貫した JSON フィールドを自動的に最適化された列に「shredding」し、ストレージ容量を 224 MB から 85 MB に削減するとともに、フィルタ処理時間を 366 ms から 63 ms に高速化します。VARIANT フィールドへのアクセスは、JSON 文字列の解析よりも約 6 倍速いです。ユーザーには現在の制限事項に注意する必要があります:高トラフィックなクエリで VARIANT リストを VARCHAR[] にキャストする場合、最大で約 2 秒かかるため、ホットパスではこうしたキャストを行わないことを推奨します。これらのハイライトに加え、リリースには履歴管理用の SQL トリガー、ネストされたスキーマ、CTE 内の DML、Spark SQL 互換性、そして外部ファイルキャッシングの改善が含まれています。CLI は、自動フォーマットされた SQL(duckdb -format)、クエリ可能な履歴、組み込みドキュメントを支援しており、「Quack」クライアントサーバープロトコルはバージョン 1.0 に到達しました。本文
DuckDB 2.0:新機能とパフォーマンスの要点解説
今年秋にリリースされる予定の DuckDB 2.0 のアルファ版が公開されています。表やパイプライン構築の開発者向けの新機能を実際に検証しました。この記事では、特に重要だと考える 3 つの主要機能 と、コミット履歴で見つけた「隠れた宝石」を解説します。
注記: 以下の数値は、M5 ラップトップと自宅インターネット回線での測定結果です。引用前にはご自身の環境でのベンチマークを実行してください。
1. 非同期 I/O:AWS S3 からのクエリが大幅に高速化
クエリの変更を加えることなく、S3 からの読み込みが劇的に速くなりました。
ベンチマーク結果
2.2 GB の Parquet ファイル(Stack Overflow の投票データ)を読み込み、1 つの列を読み取る場合:
| バージョン | 所要時間 | 改善率 |
|---|---|---|
| DuckDB 1.5.5 | 18.8 秒 | - |
| DuckDB 2.0 アルファ | 7.7 秒 | 約 2.4 倍高速化 |
- 環境:自宅インターネット回線(us-east-1 リージョン)
- クラウド環境から実行する場合はさらに高速になる可能性があります。
仕組みの解説:なぜ速くなったのか?
ファイルは約 12 万行ごとのブロックに分割されており、ダウンロードと計算(CPU)という 2 つの処理を行います。
- DuckDB 1.5.5: ワーカーが順番にダウンロード・待機・デコードを行うため、CPU がアイドル状態になる時間が発生し、並列数が最大 18 に制限されます。
- DuckDB 2.0: ダウンロード専用のスレッドプールでデータを受信し、バッファリングします。ワーカーは常に次のデータのデコードに集中できるため、ネットワークと CPU が同時に稼働します。
制御設定:read_ahead_depth
read_ahead_depthダウンロードの先読み深度を制御する設定です。
| 設定値 | 動作内容 |
|---|---|
(デフォルト) | スレッド数に基づき自動決定。非同期 I/O がオン。 |
| 従来の DuckDB 1.5.x の動作へ戻す(同期処理)。 |
他のファイル形式・規模での比較
| シナリオ | DuckDB 1.5.5 | DuckDB 2.0 アルファ | 備考 |
|---|---|---|---|
| Parquet ファイル (1 個) | 18.8 秒 | 7.7 秒 | 列数:1 つ |
| Parquet ファイル群 (23 個) | 11.8 秒 | 3.9 秒 | 合計 13.6 GB |
| CSV ファイル (1 個) | 116 秒 | 55 秒 | 約 1.7 GB |
| チューファイファイル群 (30 個) | 3.7 秒 | 3.3 秒 | 小規模ファイルは改善効果が限定的 |
小規模ファイルの注意点: 1 MB 以下の多数の小規模ファイルを保存するのは本来推奨されるプラクティスではありません。ファイル単位の往復トラフィックによるオーバーヘッドを削減できないためです。
TL;DR
S3 への接続時、ワーカーより先に別プールでダウンロードを行うことで、2 倍〜3 倍高速化が実現しました。デフォルトでは有効 (
read_ahead_depth = -1) です。
2. 再帰的 CTE:深い階層データのパフォーマンス向上
再帰的 CTE エンジンを見直し、グラフの到達可能性において 40 倍 の改善を達成しました。
仕組みの変化
再帰的 CTE は親子関係(例:組織図)を追跡するために使用されます。
- DuckDB 1.5.5: 各階層(ループ)ごとにテーブル全体を読み込み直していました(8 階層あれば 8 回全スキャン)。
- DuckDB 2.0: テーブルを1 回だけ読み込み、親列のルックアップインデックスも 1 回作成します。以降は必要な行数のみ照会するため、I/O コストが劇的に削減されます。
ベンチマーク:Git 履歴ウォーク
20,000 コミットを持つ Git リポジトリを階層構造として解析するケースです。
| 実行回数 | DuckDB 1.5.5 | DuckDB 2.0 アルファ |
|---|---|---|
| 平均所要時間 | 1.8 秒 〜 16 秒 | 0.10 秒 |
黄金律: 深い親/子チェーン(Git 履歴、系譜樹など)を扱う場合、グラフデータベースへの依存なしで高速処理可能です。階層が浅い(組織図など)場合は効果は小さいですが、
を使用して深度やコストを持つデータを一貫した表として管理すると良いでしょう。USING KEY
3. VARIANT:JSON より小さく高速
DuckDB のファーストクラスデータ型として「VARIANT」が確立されました。
シュレッディング(Shredding)の仕組み
DuckDB は JSON 列をディスクに書き込む際、同じ値を持つフィールドを発見し、内部実列として引き出します。
- 共通フィールド:
,type
など → 専用実列として格納。user.id - 多様フィールド: 型がバラバラな部分 → Blob (バイナリ) として格納。
これにより、JSON の構造を保ちつつ、テーブルのように高速にアクセスできるようになります。
ベンチマーク:JSON String vs. VARIANT
| メトリック | DuckDB 1.5.5 (JSON String) | DuckDB 2.0 アルファ (VARIANT) |
|---|---|---|
| ストレージサイズ | ~224 MB | 85 MB (2.7 倍小容量) |
| フィルタクエリ | 366 ms | 63 ms (約 5.8 倍高速) |
| 合計クエリ | 408 ms | 61 ms (約 6.7 倍高速) |
- ※1.5.5 の VARIANT(シュレッディング未適用)との比較では、フィールドアクセスが 78 倍高速です。
- シュレッディングされた場合、フィルタや合計処理において型付き列の 20% 以内の性能を発揮します。
モデリングへの示唆
クエリで頻繁に使うフィールドは実列化(Explicit Column)すべきです。
-- VARIANT から実列へ昇格する手順 ALTER TABLE ev ADD COLUMN type VARCHAR; UPDATE ev SET type = payload.type::VARCHAR;
TL;DR
共通かつ型が一貫したフィールドを持つ場合は、VARIANT を使用してください。ストレージは約 1/3 になり、クエリも実列のように高速に動作します。
リリースとコミット履歴からのお知らせ(Quick Hits)
その他の新機能や改善点です。
データベース機能
- トリガー:
で行変更時に自動で SQL を実行できます。外部ツールなしで履歴表の作成・更新が可能です。CREATE TRIGGER - ネステッドスキーマ: スキーマ内でのスキーマ作成(例:
)をサポート。finance.reports - CTE 内での DML:
を使用し、移行パターンのアトミック処理が可能に。WITH ... DELETE ... RETURNING
パフォーマンス・互換性
- 外部ファイルキャッシュのスペール: メモリがいっぱいになった際(例:300 MB 制限)、キャッシュされたブロックをディスクへ転送(スペール)します。
- 効果:854 MB Parquet の再読み込みが 23.9 秒 → 0.35 秒 へ改善。
- Spark 互換モード: Spark SQL から移行する際に有用な設定が可能 (
)。SET dialect_compatibility_mode = 'spark'
CLI 環境の改善
- SQL フォーマッター:
またはduckdb -format
でコード整形が可能。.auto_format on - クエリ履歴:
や.history
で過去の実行を検索可能。FROM shell_history() - ドキュメント:
および.about
コマンドで関数説明を参照可能。.manual <function> - JSON 処理:
が ISO-8601 タイムスタンプを自動検出し、正常に扱います。read_json
インストール方法(アルファ版)
MotherDuck を通じても利用可能です。CLI のインストール例:
curl https://install.duckdb.org | DUCKDB_VERSION=alpha bash ~/\.duckdb/cli/latest/duckdb -c "SELECT version()"