データベースが隠している「40倍の速度」という神話
あなたの分析クエリは、必要以上に大幅に遅くなっている可能性があります。1億行の集計クエリを考えてみましょう。Postgresでは、この操作に9.7秒という驚くべき時間がかかります。一方、column-storeデータベースであるDuckDBは、同じクエリをわずか0.24秒で完了し、40倍以上の速度向上を実現します。この顕著な違いは、多くの従来のデータベースに内在する根本的なアーキテクチャ上のボトルネックを明らかにしています。
Postgresのような従来のRDBはrow-storesです。これらはデータをディスク上で「行」単位で整理するため、クエリが1つの列の値しか必要としない場合でも、行全体がストレージから取得されます。多くの行にわたって少数の列を集計する分析ワークロードでは、この設計によりデータベースは膨大な無関係のデータを読み込むことになり、貴重なI/O帯域幅とCPUサイクルを浪費してしまいます。
DuckDBやClickHouseのようなcolumn-storesはこのパラダイムを逆転させます。これらはデータを「列」単位でグループ化して保存します。集計クエリが特定の列を対象とする場合、データベースはディスクからその特定の列のデータのみを読み込み、テーブル内の他のすべての列を完全にスキップします。これにより処理されるデータ量が劇的に削減され、観測されるパフォーマンスの向上が実現します。
カラム型データベースはいかにして時間を「節約」するのか
カラム型データベースは、実行する作業量を桁違いに減らすことで驚異的な速度を実現しています。すべての行をスキャンする代わりに、巧妙なインデックス作成とメタデータ戦略を採用して無関係なデータをスキップします。この効率性は、行ではなく列ごとにデータをグループ化する列指向ストレージに由来しており、列のサブセットを集計することが多い分析クエリに最適化されています。
例えばClickHouseは、個々の行にインデックスを付けません。タイムスタンプのようなソートされた列に定義されたsparse primary keyに依存しています。データが取り込まれると、それはソートされ、約8,192行の固定サイズのブロック(granulesと呼ばれます)に分割されます。ClickHouseは各granuleの最初のタイムスタンプのみを保存するため、1億行のデータセットに対して約12,000個の小さなメモリ内ノートを作成します。
クエリが3月のような特定の期間のデータを要求すると、ClickHouseはこれらのメモリ内ノートを素早くスキャンし、関連するgranuleのみを特定してディスクから読み取ります。私たちのベンチマークでは、これは12,208ブロックのうちわずか1,633ブロックを読み取ることを意味し、データセットの86%以上を無視しました。DuckDBも同様に非常に効果的なトリックを使用しています。各列のチャンクに対してmin/max metadataを保存します。これにより、DuckDBは「1月から2月にまたがるチャンク」のように、そのチャンクがクエリと無関係であることを証明し、内容を読み取ることなく完全にスキップできます。
アキレス腱:Postgresが勝る点
カラム型データベースは集計クエリには優れていますが、そのアーキテクチャは他の一般的な操作において重大なトレードオフをもたらします。IDで単一行を取得するポイントルックアップクエリは、この顕著な対比を明らかにします。Postgresでは、要求された行を含む正確なデータページへ効率的に移動するbinary tree indexのおかげで、わずか2ミリ秒で完了します。
しかし、ClickHouseはこのようなクエリを苦手としており、168ミリ秒かかります。タイムスタンプとIDでソートされたsparse primary keyは、12,208個のデータブロックすべてをスキャンしなければ、任意のIDへの直接的なパスを提供しません。行を見つけた後でも、8つの列ファイルすべてを開いて結合し、完全なレコードを再構築する必要があり、一見単純な取得操作に対してかなりのオーバーヘッドが発生します。
単一行の更新は、アーキテクチャの相違をさらに浮き彫りにします。Postgresでは、更新は5ミリ秒で完了し、1行を書き換えて1つのインデックスエントリを更新します。対照的に、ClickHouseでは同じ操作に5.8秒という驚異的な時間がかかります。これは、ClickHouseが不変データファイル(immutable data files)を採用しているためです。単一の値を変更するには、影響を受けるデータチャンクの収益カラムファイル全体を書き換える必要があります。
これらのパフォーマンス特性は設計上の欠陥ではなく、固有の専門化によるものです。Postgresのような行指向データベースは、頻繁な単一行の挿入、更新、検索が最優先されるトランザクションワークロード(OLTP)に最適化されています。一方、カラムナデータベースは、膨大なデータセットに対する集計クエリが中心となる分析ワークロード(OLAP)を優先するように設計されており、ユースケースに応じて強みと弱みが明確に分かれます。
この記事が気に入ったら、毎朝同じようなものをメールで受け取れます。
1日1通 · 2クリックで解除 · サードパーティのトラッキングなし
ClickHouse vs. DuckDB: あなたの武器を選ぼう
分析クエリを高速化するための2つの異なるカラムナオプションとして、ClickHouseとDuckDBが存在します。どちらも集計操作においてPostgresよりも優れたパフォーマンスを発揮しますが、そのアーキテクチャの哲学は大きく異なり、理想的なアプリケーションも異なります。
ClickHouseは、本番環境のデータウェアハウス向けに構築された、フル機能を備えたサーバーベースのシステムとして動作します。Postgresと同様に、実行中のサーバーインスタンスを必要とし、堅牢な共有分析環境のために同時マルチユーザーアクセスをサポートしています。
対照的に、DuckDBは分析ワークロードのためのSQLiteのような組み込みライブラリ体験を提供します。アプリケーション内でインプロセスで実行され、データベース全体をディスク上の単一ファイルに保存するため、ローカルでのクライアントサイドのデータ操作に最適です。
複数のユーザーと大規模なデータセットをサポートするスケーラブルな共有分析バックエンドには、ClickHouseが最適です。本番環境において、ペタバイト規模のデータに対する高スループットな取り込みと複雑な集計クエリを処理します。
ローカルでのデータ分析を強化したり、シングルノードアプリケーションを動かしたり、超高速なETLジョブを加速させたりするには、DuckDBを選択してください。そのインプロセスという性質と単一ファイルデータベースは、個々のデータサイエンティストや小規模な社内ツールのデプロイを簡素化します。
堅牢なマルチユーザー分析プラットフォームが必要な場合、DuckDBは適していません。ニーズがローカルでのシングルユーザー処理に限られている場合、ClickHouseのサーバーオーバーヘッドは不要です。
よくある質問
カラムナデータベースと行指向データベースの主な違いは何ですか?
行指向データベース(Postgresなど)は、1つのレコードのすべてのデータをまとめて保存します。カラムナデータベース(ClickHouseなど)は、1つのカラムのすべての値をまとめて保存するため、分析クエリに対してはるかに効率的です。
カラムナデータベースはいつ使用すべきですか?
数百万から数十億行にわたる少数のカラムを集計またはフィルタリングする分析ワークロード(OLAP)には、カラムナデータベースを使用してください。ダッシュボード、ビジネスインテリジェンス、分析プラットフォームに最適です。
なぜカラムナデータベースは単一行の更新が遅いのですか?
そのデータファイルは一括取り込み用に最適化されており、多くの場合不変(immutable)だからです。単一の値を更新するには、カラムファイル内の大きなチャンク全体を書き換える必要があり、トランザクションデータベースよりもはるかに低速になります。
DuckDBはPostgresの代替品ですか?
いいえ、主な目的が異なります。DuckDBは組み込み型の分析データベース(分析のためのSQLiteのようなもの)であり、インプロセスでのデータ分析に最適です。Postgresは、記録システムとして設計された汎用的なトランザクションデータベース(OLTP)です。

