ハクソク

世界を動かす技術を、日本語で。

DuckDBがデータ処理の第一選択である理由

概要

  • DuckDBはシンプルで高速なインプロセスSQLエンジン
  • Pythonとの親和性が高く、データ処理の主力ツールとして利用拡大
  • インストールやテストが容易で、CI/CDにも最適
  • 多彩なSQL機能やファイル形式対応、拡張性も魅力
  • 中規模データの分析基盤として、従来のクラスタ構成からの移行が進行中

DuckDBの特徴と利点

  • DuckDBは、アプリケーション内で動作するオープンソースSQLエンジン
  • インプロセス型で、SQLiteのように別サービスの起動不要
  • 分析クエリ最適化が強みで、大規模な結合や集約に特化
  • OLAPエンジンとして、SQLiteやPostgresより100~1,000倍高速な場合も
  • CSV、Parquet、JSONなど様々なファイル形式のバッチ処理に最適
  • コマンドラインからのCSV閲覧など、軽量な用途にも対応

高速性とインストールの容易さ

  • 高速ベンチマークでPolars、DataFusion、Spark、Daskと並ぶ性能
    • SparkやDaskは大規模データで競合するが、小規模ではDuckDBが優位
  • 単一バイナリで提供、Pythonならpip installのみで依存関係なし
  • uvと組み合わせることで、1秒未満でPython環境構築が可能

CI・テスト環境との親和性

  • 高速起動・シンプルなセットアップでCIやパイプラインテストに最適
  • Spark等の従来エンジンよりテストの手間や環境差異が大幅減少

SQL記述の快適さ

  • 素早い実行とシンプルな記法でSQL開発がスムーズ
  • SparkやAthenaに比べ、ローカルでの反復開発が容易
  • DuckDB UIではオートコンプリート機能も利用可能

使いやすいSQL構文

  • EXCLUDECOLUMNS(正規表現によるカラム選択・置換)など独自拡張
  • QUALIFYやウィンドウ関数の集約修飾子もサポート
  • 関数チェーン(例:first_name.lower().trim())が可能で直感的

多様なファイル形式への高速対応

  • S3やWeb上のファイルも直接クエリ可能
    • 例:select * from read_parquet('https://raw.githubusercontent.com/plotly/datasets/master/2015_flights.parquet') limit 2;
  • CSV等の非型付きデータにも厳格な型指定オプションあり

Python APIの利便性

  • CTEの連鎖によるパイプライン構築が容易
  • duckdb.sql()で各処理ステップをPython変数化し、途中結果の確認も簡単
  • 遅延実行でパフォーマンス低下なし、各ステップを独立してテスト可能

ACID準拠とミドルスケール分析基盤

  • バルクデータ操作における完全なACID準拠
  • IcebergやDelta Lakeのようなレイクハウスの代替候補として注目
  • 詳細は公式ポッドキャストやドキュメント参照

高性能UDFとコミュニティ拡張

  • C++で高性能UDF開発が可能、従来のSparkに比べて配布が容易
  • コミュニティ拡張はINSTALLコマンド一発で導入可能
    • 例:INSTALL h3 FROM community(地理空間用インデックス)

ドキュメントの充実

  • Markdown形式で提供され、LLMやエディタでの活用が容易
  • コードフォールディングで必要部分だけ抜粋しやすい

Splinkでの実績と開発効率

  • Splink(大規模レコードリンケージOSS)でDuckDB推奨により導入増加
  • ユーザーの問題減少・処理速度向上・開発/テスト効率化を実現

今後注目の拡張

  • PostgreSQL ExtensionでPostgres DBへ直接クエリが可能
  • pg_duckdbでPostgres内にDuckDBエンジンを組み込み、
    • トランザクションと分析処理の両立が期待
  • Postgresインデックス活用やフィルタープッシュアップ等、今後の改善に期待

補足

  • 大規模クラスタ不要な時代の到来、DuckDBの分散版も登場
  • Sparkの複雑な設定からの解放、中規模データ分析の新定番としての地位向上
  • Athenaのようなプロプラエタリ環境に比べて開発サイクルが高速

Hackerたちの意見

CSVやjson/jsonlファイルでSQLを使えるのはめっちゃいいね。もちろん、それ以上のこともできるけど、俺はそれが一番多い使い方だよ。duckdb大好き。
確かに!俺はシンプルなCSV/TSVの処理にはawkが好きだけど、複数のCSVファイルを結合したり、特定のカラムを集計したりする場合は、SQLが本当に輝くと思う。
著者の考えは基本的なデータ処理には妥当だと思うけど、それ以外の主張、例えば「ほとんどの表形式データは単一の大きなマシンで処理できるシンプルな世界に向かっている」っていうのは、かなり議論の余地があるね。データをどうピボットしたりスケールしたりするかによっては、一見「収まる」データセットでもすぐにメモリ不足になることがあるよ。著者は別の記事でも「新しいデータエンジニアリングの作業にはSQLが最初に考慮されるべき選択肢だ」と言ってるけど、これは俺の経験とは全然合わないな。複雑な分析や拡張をあまり必要としない、きれいにパースされたデータセットの範囲外ではね。
SQLが人気なのは、みんなが学んで使い始めるのが簡単だからだよね。Pythonの方が良いツールになることもあるけど、SQLがなくなることはないと思う。俺の経験では、データモデリングの面ではまだSQLが圧倒的に多いよ。ただ、データの取り込みはほとんどPythonやScalaだけどね。
著者です。「SQLが最初に考慮されるべき選択肢」とのことですが、pandasやpolarsのような他のデータフレームAPIにも確かに利点がありますし、瞬間的にはどれかがSQLより優れていると言えるかもしれません。今はPolarsが注目されていて、高品質なAPIです。ただ、エコシステムがどれかに標準化されていないのが問題で、データフレームAPIを変えるたびにパイプラインを再構築しなきゃいけないのが面倒です。データが巨大な場合はメモリ不足になることもあると思いますが、一般的に人々が処理する表形式データの大半は10GB未満で、それなら単一の大きなマシンで問題なく処理できると思います。私の経験では、Sparkが必要ないほど小さなデータセットでも使われているのをよく見ます。DuckDBは注目を集めているけど、今の時代、ノートパソコンで数GBのデータをすぐに処理できることに気づいていない人が多いみたいです。全体的には、DuckDBを最初に使うことを考えるのは良いアイデアだと思います。多くの場合、すぐに簡単に仕事をこなしてくれますからね。適切でないシナリオもたくさんありますが、始めるにはいい場所だと思います。
500GBのParquetを大きめのデスクトップ(50GB RAM)でDuckDBを動かしてるけど、スムーズで速いよ。OOMの問題はそのうち出てくるかもしれないけど、現実のユースケースの中では上位1%に入ると思う。
そうだね、私も同じく混乱してる。 >「新しいデータエンジニアリングの作業にはSQLが最初に考慮されるべき選択肢だ。堅牢で、速くて、将来にわたって使えるし、テストもできる。ちょっと気を使えば、明確で読みやすい。」(ポーラーやパンダなどと比べて)SQLは速さとは関係ないと思うけど、ポーラーよりもテストしやすい理由って何だろう?将来にわたって使えるってどういう意味?SQLの方言が壊れる変更がないってことかな?
最近はAWSで32TiBのRAMインスタンスが手に入るよ。
私の経験では、MLや可視化、先進的な分析をしたいなら、データフレームの方が良い体験ができるよ。パイプラインでデータをシャッフルするなら、SQLでもいいけどね。読みやすさは見る人によるから。私はデータフレームの方が好きだけど、ネットの一部では見ただけで吐きそうになるって言ってる人も多いね…
duckdbの好きなところ: -- .parquet、.json、.csvをサポートしてる(Spotifyのリスニング履歴が複数の.jsonファイルで来るのが面白い)。 -- glob読み込みをサポートしてるから、例えば「select * from 'tsa20*.csv'」みたいに、何百ものファイルを一つのファイルのように読み込める。 -- ファイルのスキーマが同じじゃなくても、union_by_nameがすごい。 -- .csvパーサーが優秀で、自動で型をうまく割り当ててくれる。 -- 小さい!Web Assembly版は2MB、CLIは16MB。 -- 小さいから、duckdbを直接製品に組み込める。Malloyがやってるみたいにね: https://www.malloydata.dev/ MalloyはPowerBIやTableauの技術者向けの代替品だと思ってるけど、AIがデータに対して素晴らしいクエリを書くのを助けるセマンティックモデルを使ってる。編集:Malloyはそのセマンティックな特性のおかげでSQLを書くのが10倍簡単になるよ。MalloyはSQLにトランスパイルする、TypescriptがJavascriptにトランスパイルするみたいにね。
MalloyとPRQLはめっちゃクールだね!
解凍したら32MB、圧縮すると約6MBだから、そんなに小さくはないよね。https://cdn.jsdelivr.net/npm/@duckdb/duckdb-wasm/dist/ それに、SQLiteに比べてカスタマイズが難しいから、例えばCSV用の独自のパーサーを使いたい場合は大変だよ。でも、確かに便利な機能がたくさんあるのはその通り。
これは素晴らしい提案だね。私はSQLiteのインポートとかで面倒な手作業をしてるから、これはありがたい。ありがとう!
素晴らしいコメントありがとう!じゃあ、DuckDBで遊ぶためにSpotifyの履歴をエクスポートしてくるね <3
>> .csvパーサーは素晴らしい 彼らのCSVサポートは、たくさんの関数と速くて簡単なデータ探索と組み合わさって、調査のアプローチを完全に変えた。以前は問題のスキーマを理解するのにかなりの時間をかけてたけど、実際にはスキーマがないことが多くて、簡単にはわからなかった。今はデータを引っ張ってきて、仮説を検証するための探索的クエリを書いて、データをクリーンアップして変換し、その状態から新しいテーブルを作る。これを繰り返すことで、より深く早く進めるし、早めに行き詰まるから、無駄な時間をかなり節約できる。CSVパーサーの仕組みや将来の改善案についての興味深い論文があるけど、見つけられなかったな。誰か見つけられる人いる?
-- Hiveパーティショニング
最近Clickhouseをいじってて、すごくいい体験をしてるよ。特に、これらのポイントに多くヒットしてるからね。私の場合、「ローカルファイル」はあまり重要じゃなかったけど、ParquetやJSONの取り込みはすごく便利だった。CHは`clickhouse-local`を「duckdbを追加する」ポイントのアナログにするつもりだと思う。一番好きな機能の一つは、`SELECT ... FROM s3Cluster('', 'https://....../data//.json', ..., 'JSON')`で、これを使うとS3バケットからワイルドカードで取り込めて、設定したクラスターのノードに処理を分散できるんだ。あと、`schema_inference_mode`(下で言及されてるやつ)とも連携してると思うけど、まだ試してないんだ。データベースやDBツールにとってすごく面白い時期だね。(実は`union_by_name`には詳しくなかったけど、Clickhouseでも実装されてるみたいだね [1,2] どちらにしても面白い機能だ!)
duckdbを使って、数十億のレコードと30カラムを持つ単一テーブルからフィルタリングされたトランザクションのページを素早く選択する経験がある人いる?簡単なWHERE句でフィルタリングできるやつね。例えば、10年間の支払い注文データとか。これは分析シナリオじゃないから気になってるんだけど、Postgresでやると時間がかかるし、単純なcount(*)でもかなり時間がかかる(すべてのカラムにインデックスが付いてるのに)。
この規模でDuckDBをたくさん使ってきたけど、こんなのが数秒以上かかるとは思えないな。遅いDuckDBのクエリは、複雑な結合や多くのファイルを対象にしたグロブが含まれている場合だけだよ。
一般的なインデックスアルゴリズムがカウントを早くするのに役立つかはあまり自信がないな。テーブルはどれくらいの頻度で更新されてる?もし頻繁に更新されていて、カウントのクエリもよくあるなら、カウントを定期的に実行して結果を別に保存するのがいいかも。逆にあまりクエリがないなら、頻度を下げてもいいと思う。君が言ってる感じだと、WHERE句の下にあるカラムと値のペアのリストは、インデックスを使えばかなり早く解決できるはずだよ。大量のデータを一度に引っ張り出さなければね。
たった10分前、メインフレームから生成された非常に大きな半整形のExcelファイルを扱ってたんだけど、DuckDBはそれをall_varchar(すべてを文字列として保持)で1秒以内にロードできたよ。まだExcelがファイルをロードするのを待ってるところ。
これ、私のお気に入りのツールになったよ!私はBCの沿岸環境を研究している科学者たちと一緒に仕事してるんだけど、氷河の空中観測から深海の自律ドローンまで、データがめちゃくちゃあるんだ。少し前に、DuckDBをデータ処理エンジンとして使う新しいツールに挑戦したんだ。目的は、たくさんの既存のデータセットを有効なダーウィンコアデータに変換すること。キーワードは「有効」ね。この文脈ではDuckDBが本当に素晴らしいツールなんだ。基本的には、データを説明するスキーマからDuckDBのテーブルを動的に構築して、それをテーブルにインポートする感じ。もし失敗したら、行ごとに理由を説明してくれる(できる限りだけど)。生データが入ったら、変換が行える。これも全てDuckDB内で完結するよ。最後に、変換だけでは不安な場合はアプリケーション層のロジックを使って検証も行う。予想以上に速くて、能力も高くて、作るのも簡単なアプリケーションを作れたよ。そして、持ち運びもできる!ブラウザでコアを全部動かせると思う。現場の研究者がiPadのブラウザでオフラインでこれを動かせるなんて、すごいよね。DuckDBをもっと上手に使えるようになるのが楽しくて仕方ない。ここ数年での一番の発見かも。もちろん、これを実現する方法はいくつもあったと思う。全然違うルートのプロトタイプもあったけど、DuckDBにたくさんの重い作業を任せられるのがいいところ。時々SQLで起こることがあまり好ましくないこともあるけど、そのトレードオフには満足してる。アプリケーション層の型安全性が欠けている場合は、パースとテストを使ってDBの抽象化が期待通りに動いているか確認してる。これが本当にうまくいってるよ!編集:興味がある人のために、このプロジェクトの目的は、科学者が特注のツールではなく一般的なツールを使って生物多様性やゲノムデータをもっと簡単に分析できるようにすること、そしてそれを公開リポジトリに発表することなんだ。発表は大きな課題で、現場の人たちはダーウィンコアの仕様からかなり離れたところで作業してるからね :) もう少し磨きをかけて、他の組織にも使ってもらえるようにするのが楽しみだよ。
100%同意! > SQLコードを書くことは、言語統合が中規模・大規模プロジェクトにとって重要だよね。実験的なJava言語プロジェクト、manifold-sql [1] が不可能を可能にしてる:インラインのネイティブDuckDB SQL + 型安全性。 """ [.sql/] SELECT station_name, count(*) AS num_services FROM 'http://blobs.duckdb.org/train_services.parquet' WHERE monthname(date) = 'May' GROUP BY ALL ORDER BY num_services DESC LIMIT 3 """ .fetch() .forEach(row -> out.println(row.stationName + ": " + row.numServices)); 1. https://github.com/manifold-systems/manifold/blob/master/doc...
Blueskyの分析やフィードの処理にDuckDBを使ってるよ。クエリ結果に素早くアクセスするために、Apache Arrowインターフェースを使って、DuckDBのSQLクエリから直接コードを生成するSQGツールを使ってるんだ。https://sqg.dev/generators/java-duckdb-arrow/
あなたたちの技術の裏側を見てみたいな。どこかに書いてあるものはある?あなたたちのHNツールも期待できそうだね!
DuckDBのファンなんだけど、実際にプロダクションでも使ってるんだ。でも、偶然にも今日はメモリ使用量を調べてて、メモリリークを見つけたかもしれない。似たような経験した人いる?まだ深くデバッグ中だけど、今のところ結構決定的な感じ。
私が見た限りではかなり決定的な結果だよ: https://github.com/duckdb/duckdb/issues/20569 これについて説明できる人や、修正案がある人がいたら教えてほしいな!
duckdbが大好きで、できるだけ使ってるよ。ただ、node/bunのサポートがpythonと同じくらい良ければいいのにって思う。あと、node/bun用にもう少し違った形でバンドルしてくれたらな。今のままだと、ライブラリへの動的リンクに依存してるから、bunの実行ファイルにバンドルできないんだよね。