Play
Databricks vs Snowflake。双方に熱烈な支持者がいて、いつまで経っても決着のつかない論争です。かつてはこの2つのプラットフォームのターゲット層は明確に分かれていました。Snowflakeはアナリストや従来型のBIチーム向け、Databricksは機械学習エンジニアやデータサイエンティスト向け、といった具合です。しかし現在では両者の機能はほぼ拮抗し、ほとんどすべての利用者層をカバーするようになりました。それでも論争は止みません。「Snowflakeは高い」「Databricksは遅い」、あるいは[適当な悪口を挿入]——こうした応酬はLinkedInやRedditで日常茶飯事で、熱心なファンや一方の企業の従業員から発信されています。
SELECTでは、偏りがなく、再現性があり、実用的なベンチマークを実施したいと考えました。Pythonジョブを実行すればクエリが走り、結果が記録される、ソフトウェア駆動型の仕組みです。新しいプラットフォームも簡単に追加できる設計とし、最後に見やすいビジュアライゼーションも用意しました。この公平な比較をお届けするため、(おそらく不合理なほどの)多大な労力を注ぎ込んでいます。
始める前に大事な注意点を一つ。ベンチマークは、あくまでそのベンチマーク自体がどれだけ速く走ったかを示すものにすぎません。本番ワークロードを再現するものではなく、皆さんのデータと皆さんのSQLで何が起きるかを予測できるわけでもありません。このデータから一定の結論は導けますが、ぜひご自身のデータと設計パターンで検証してみてください。
セットアップ
データ
本ベンチマークではTPC-H 1000 Scale Factorを使用しました。このデータセットは最大テーブルで約60億行を持ちます。SnowflakeとDatabricksはどちらもTPC-Hデータを備えていますが、サイズが揃っていなかったり、まったく同じ大規模データセットが用意されているわけではありません。同じ土俵で比較するには、SnowflakeからDatabricksへデータをETLする必要があります。最も簡単なのはEstuaryのような専用ツールを使う方法ですが、自前で行うことも可能です。
Databricksに用意されているのは次の通りです。
- tpcds_sf1 と sf1000
- tpch(3,000万行)。これはSnowflakeのスケールファクター10(6,000万行)の約半分のサイズです。
Snowflakeに用意されているのは次の通りです。
- tpcds_sf10 と 100
- tpch(スケールファクター1、10、100、1000)
案の定、両プラットフォームとも似たサンプルデータを揃えておらず、性能比較を難しくしています。🤨
シナリオ
既存の標準クエリを以下の3シナリオで使用しました。
- 22クエリすべてを逐次実行。 このシナリオではクエリ1のみがコールドスタートで、それ以降のクエリは先行クエリのウェアハウスキャッシュの恩恵を受けられます。
- 22クエリすべてを並列実行。 ここでは、データプラットフォームが複数クエリを同時に処理する能力と、水平スケーリングが観察されるかどうかを検証します。
- コールドスタートクエリ5本。 複雑さやスタイルの異なるクエリを少数選び、コールド状態のウェアハウスで両プラットフォームを比較します。
CTASワークロード: 標準ベンチマーククエリは結果セットが小さく、ほとんどが高度に集約されているため、書き込みのペイロードが小さすぎて書き込みスループットを十分にストレステストできず、実際のCTASワークロードを表すには不向きでした。そこで書き込み集約型の処理を検証するため、データ形状の異なる5つのバリエーション(数十億行の細長いテーブルから、極端に幅広い非正規化テーブルまで)を作成し、テーブル形状とクエリの複雑さに応じた書き込み性能を比較できるようにしました。
DMLワークロード: ここではテーブルから1か月分のデータを削除し、再挿入します。1か月分はデータ全体の約1%、約600万行に相当します。これはクエリプルーニングの効率(対象1か月を正確に絞り込めるか)と、DMLの効率の両方を試すテストです。
ウェアハウス
各実行・シナリオの開始時に新しいウェアハウスを自動生成し、作業が終わり次第すぐに破棄します。これにより、ウェアハウスの総コストを単独で測定でき、アイドル時間を排除できます。
Databricks Serverless SQL Warehouseは、おおむねSnowflake Warehouseの1サイズ大きいものに相当します。たとえばDatabricksのSmallはSnowflakeのMediumに相当します。上記4シナリオを、以下のウェアハウスの組み合わせで実行しました。
- Snowflake Medium vs Databricks Small
- Snowflake Large vs Databricks Medium
- Snowflake XL vs Databricks Large
このサイズ対応はSnowflakeとDatabricksのドキュメントにも裏付けられており、Databricks Worker CountとSnowflakeクレジットが同数であるという前提に基づいています。
コスト配賦
コスト配賦は可能な限り正確に行いたいと考えました。そのため、前述のように分離されたウェアハウスを用いています。ウェアハウスのライフタイム中の実際の課金データ(クレジットまたはDBU単位)を採用し、最後に柔軟なコスト計算機でクレジット単価やDBU単価を当てはめ、各プラットフォームの料金ティアをシミュレートします。このアプローチにより、並列実行クエリへの配賦や最低課金単位といった複雑さをすべて排除し、シナリオ全体の総コストだけに着目します。
実行全体ではなく個別クエリのコストを示す場合は、実行時間の比率に応じてそのクエリにコストを按分しています。つまり、実行全体(またはウェアハウスのライフタイム)の総コストをクエリ間で分配しているため、合計値が一致します。
コスト比較
Databricks Standard Tierは廃止予定(おそらく2025年10月時点で廃止済み)です。したがって各プラットフォームの最低リスト価格を比較するなら、Snowflake Standard($2/クレジット)対 Databricks Enterprise($0.70/DBU)になります。Snowflake StandardはTime Travelが欠けている以外は完全版のSnowflakeなので、この比較は公正だと考えています。とはいえ、Enterprise同士で比べたいという読者が多いことも理解しています。そこで、Databricks $0.70/DBU 対 Snowflake $2/クレジット、および $3/クレジットの両方を提示します。
実行履歴と分析
クエリIDと実行統計はローカルのduckdbに即座に記録されます。データはクエリID粒度(さらに実行ID、ウェアハウス、シナリオを含む)で保存されます。レポートビューでデータを集約することで、実行全体にわたる結論を導き出せます。
クエリ
ベンチマーク用クエリはこちらで確認できます。(SQLは一見スケールファクター100xにハードコードされているように見えますが、テーブル名は実行時に設定ファイルのスケールファクターで動的に置換されます。すべてのテストは1000xスケールファクターで実施しました。)22個のクエリは複雑さとJOIN数に基づいてカテゴリ分けしています。詳細な分類はこちらにありますが、スクリーンショットで要点をまとめています。
シナリオ1:22クエリの逐次実行
目的とセットアップ
目的: クエリを逐次実行することは、自席でデータプラットフォームに対してクエリを投げる状況を模しています。エンドユーザーがSELECTクエリを実行したときに体感するのと同じ動きです。この計測により、一般的なTPC-Hベンチマークと同じく、クエリごと・ウェアハウスごとの比較が可能になります。
セットアップ: 仕組みは至ってシンプルで、22クエリを1本ずつ実行するだけです。すべてのシナリオで、ウェアハウスは実行開始時に作成され、最後のクエリ完了直後に破棄されます。クエリ結果は即座にduckdbへ記録されます。
このシナリオで真の「コールドスタート」となるのはクエリ1のみで、クエリ2〜22はウォーム状態とみなされます。ウェアハウスは実行中ずっと起動したままだからです。
結果
Snowflake $2/クレジット 対 Databricks $0.70/DBU:
Snowflake $3/クレジット 対 Databricks $0.70/DBU:
$2/クレジットの条件下では、Snowflakeが34%速く、17%安いという結果になりました。Snowflakeを$3/クレジットに引き上げると、Databricksの方が20%安くなります。
シナリオ2:22クエリの並列実行
目的とセットアップ
目的: これはBIダッシュボードの読み込みや、数十のクエリが一斉に発行されるジョブをシミュレートしています。各データプラットフォームが並列処理をどう捌くかを検証するのが狙いです。
セットアップ: Pythonで22クエリを一斉に発行し、結果を記録しました。
結果
Snowflake $2/クレジット 対 Databricks $0.70/DBU:
Snowflake $3/クレジット 対 Databricks $0.70/DBU:
両シナリオとも、Snowflakeの方が速くて安いという結果になりました。つまり並列ワークロードに関しては、(このベンチマーク条件下では)Snowflakeに軍配が上がりそうです。
ここで、各プラットフォームが並列処理をどう捌いたのかを掘り下げてみましょう。並列処理が完璧に機能している(キューイングやリソース競合がない)なら、並列テストの総実行時間は、単独で実行したときに最も長くかかるクエリの実行時間とほぼ同じになるはずです。
| プラットフォーム | ウェアハウスサイズ | 単独実行時の最長クエリ | 並列実行時間 | 倍率 |
|---|---|---|---|---|
| Databricks | SMALL | 134.5 秒 | 369.5 秒 | 2.7倍 |
| Databricks | MEDIUM | 64.5 秒 | 296.0 秒 | 4.6倍 |
| Databricks | LARGE | 32.9 秒 | 176.5 秒 | 5.4倍 |
| Snowflake | MEDIUM | 94.7 秒 | 278.7 秒 | 2.9倍 |
| Snowflake | LARGE | 45.2 秒 | 142.8 秒 | 3.2倍 |
| Snowflake | XLARGE | 20.7 秒 | 99.7 秒 | 4.8倍 |
上記のデータからは、両プラットフォームとも並列実行にはペナルティがある(同時に複数クエリを走らせるとどれも遅くなる、あるいはキューイングが発生する)ものの、この比較ではSnowflakeの方が良好な比率を示していることが分かります。
22クエリを並列実行した際、SnowflakeはMediumとLargeで最大4クラスターまでスケールアップし、XLでは3クラスターしか使いませんでした。XLがLargeとほんの数セントしか変わらない理由はここにあります。
残念ながら同じ情報はDatabricksでは確認できませんでした。クラスターがいくつ使われたかを知る手段が見つけられなかったのです。
シナリオ3:コールドスタート
目的とセットアップ
目的: 「ウェアハウスキャッシュ」がない状態でのクエリ実行時間を計測し、ウェアハウスの起動時間が結果に影響するかどうかを確認します。
両プラットフォームとも「ウェアハウスキャッシュ」や「Photonアクセラレーション」を活用しています。これらはクエリを実行するVM上に存在するキャッシュです。クエリを逐次実行する場合、クエリ2はクエリ1で生成されたキャッシュの一部を活用できる、といった具合に効きます。
セットアップ: キャッシュがない状態でクエリがどう振る舞うかを見るため、各クエリ実行の合間にウェアハウスをシャットダウンするシナリオを設計しました。今回は22クエリすべては実行していません。コストがかさみすぎるためです。
ウェアハウスの作成時間は総ウォールクロック時間に含めませんが、ウェアハウスの起動時間は総ウォールクロック時間に含めています。
クエリ
| クエリ | カテゴリ | 複雑度 | 説明 |
|---|---|---|---|
| Q1 | シンプルな集計とフィルタリング | 低(ウォームアップ) | 6億行テーブルに対するGROUP BYと複数の集計(SUM、AVG、COUNT) |
| Q3 | 基本的なJOIN(2〜4テーブル) | 中(標準OLAP) | 集計と日付フィルタを含む3テーブルJOIN |
| Q5 | 複雑なJOIN(5テーブル以上) | 高(ストレステスト) | 収益計算と地域フィルタを含む6テーブルJOIN |
| Q10 | 基本的なJOIN(2〜4テーブル) | 中(標準OLAP) | 選択的フィルタと高カーディナリティGROUP BYを含む4テーブルJOIN |
| Q18 | サブクエリとセミJOIN | 中(標準OLAP) | 集計フィルタ(HAVING)を伴うINサブクエリ |
Query Category Complexity Description Q1 シンプルな集計とフィルタリング 低(ウォームアップ)6億行テーブルに対するGROUP BYと複数の集計(SUM、AVG、COUNT)Q3 基本的なJOIN(2〜4テーブル)中(標準OLAP)集計と日付フィルタを含む3テーブルJOIN Q5 複雑なJOIN(5テーブル以上)高(ストレステスト)収益計算と地域フィルタを含む6テーブルJOIN Q10 基本的なJOIN(2〜4テーブル)中(標準OLAP)選択的フィルタと高カーディナリティGROUP BYを含む4テーブルJOIN Q18 サブクエリとセミJOIN 中(標準OLAP)集計フィルタ(HAVING)を伴うINサブクエリ
結果
このシナリオではSnowflakeが桁違いに速く、コストもやや安いという結果になりました。
詳細を見ると、Databricksの起動時間は1回あたり約7秒、Snowflakeの起動時間は全ケースで1秒未満でした。
シナリオ4:CTAS(Create Table As Select)
目的とセットアップ
目的: データエンジニアリングの業務やdbtプロジェクトで典型的な、書き込み集約型の処理を計測します。標準のTPC-Hクエリは分析的な読み取りに最適化されており、大規模なデータセットをスキャンしつつも返すのは小さく集約された結果(合計、平均、上位N件)です。これはクエリ実行と最適化のテストにはなりますが、書き込み性能のストレステストにはなりません。私たちは、SnowflakeとDatabricksが多様な形状の数十億行を書き込む際にどう違いが出るのかを知りたかったのです。
セットアップ: 5つのCTASバリエーションを作成し、それぞれが特定の書き込みパターンを検証するよう設計しました。
- 細長型(60億行 × 4列):LINEITEMテーブルからキー列4つ(l_orderkey、l_partkey、l_quantity、l_extendedprice)のみを射影したシンプルなパターン。列のオーバーヘッドを最小化した状態での最大行スループットを検証します。
- 標準縦長型(60億行 × 16列):LINEITEMテーブル全体のコピー(SELECT * FROM LINEITEM)。大規模なファクトテーブルを複製・アーカイブする一般的なパターンを表します。(通常はCloneを使う場面ですが、今回はClone操作のベンチマークは行っていません。)
- 中幅型(15億行 × 30列):ORDERS、CUSTOMER、NATION、REGIONテーブルのJOIN。中程度のJOIN複雑度と広めのスキーマで、スタースキーマの非正規化に典型的な、読み取りと書き込みを組み合わせた性能を検証します。
- 超幅広型(60億行 × 59列):TPC-Hの全テーブル(LINEITEM、ORDERS、CUSTOMER、SUPPLIER、PART、PARTSUPP、NATION、REGION)をまたぐ完全非正規化JOIN。分析レイヤーでよく見られる、極端に幅広く事前JOIN済みのテーブルの極端なケースを表します。
- フィルタ型(20億行 × 16列):1995年以降に出荷された注文に絞ったLINEITEM(WHERE l_shipdate >= '1995-01-01')。部分的なテーブルコピーの書き込みスループットを検証します。これは増分データパイプラインで一般的なパターンです。
結果
Snowflake $2/クレジット 対 Databricks $0.70/DBU:
Snowflake $3/クレジット 対 Databricks $0.70/DBU:
Snowflake $2/クレジット 対 Databricks $0.70/DBU(「超幅広型」の外れ値クエリを除く):
Snowflake $3/クレジット 対 Databricks $0.70/DBU(「超幅広型」の外れ値クエリを除く):
このベンチマーク条件下では、CTASによる大規模テーブル作成においてDatabricksが明確な優位性を持つと言って差し支えないでしょう。
シナリオ5:DML(データ操作言語)
目的とセットアップ
目的: Delete + Insertはデータを増分更新する際によく使われるパターンです。大規模テーブルの特定セグメントを変換する最も効果的な方法であり、検証すべき重要なシナリオです。
セットアップ: 実行開始時に、ソースとなるベンチマークデータのコピーを作成します。これは実行時間やコスト指標には含めません。コピーが作成されたら、ベンチマーク処理を開始します。1か月分のデータ(約600万行、全体の約1%)を削除し、その後ソースから同じ1か月分を再挿入します。これは、マッチしたレコードを削除して挿入する現実のETLシナリオを再現したものです。なお、mergeは使用していません。delete + insertの方がmergeより速いことはよく知られているためです。
結果
Snowflake $2/クレジット 対 Databricks $0.70/DBU:
Snowflake $3/クレジット 対 Databricks $0.70/DBU:
ここでの結果は非常に興味深いものでした。Snowflake M、L、XLがいずれも20秒未満で処理を終えられるのは、優秀なクエリプルーニングのおかげです。60億行が600万行相当にまで絞り込まれ、はるかに小さなデータセットに対して処理が行われています。Smallウェアハウスで2倍以上の時間がかかっているのは、削除と挿入の両ステップでスピレージが発生したためです。
Databricksでも同じことが起きています。すべてのウェアハウスサイズで処理時間が35〜39秒の範囲に集中しています。Databricksも実質的にデータセットのサイズを削減できているため、M、L、XLは難なくこなしていますが、Snowflakeほどの速さには及びません。
このベンチマークを再現するには
このテストをご自身で実行したい場合、比較的簡単に行えます。前述の通り、最初にやるべきことはSnowflakeからDatabricksへ1000xデータセットをETLすることです。これが最も大変な部分であり、変数が多すぎるため自動化を提供していない唯一のステップです。重ねてになりますが、Estuaryの利用をおすすめします。
Databricksアカウントでデータが利用可能になったら、こちらのスタートガイドに従ってください。UVとSnowflake CLIをインストールし、uv run setup_config.pyを実行して.envファイルを設定すれば、ベンチマークを開始できます。READMEには、個別シナリオやウェアハウスサイズの実行、あるいは全体を一気に走らせる方法など、豊富な実行例が掲載されています。
ベンチマーク実行後は、課金データが確定するまで2時間待つ必要があります。その後uv run enrich.pyを実行して、結果を課金データで補強します。結果を可視化する準備ができたら、こちらもREADMEの手順に従って進めてください。
まとめ
結果から明確に言えるのは、Snowflake Standard EditionがCTASシナリオを除くすべてのシナリオで最もコスト効率の良いプラットフォームだということです。CTASシナリオではDatabricksがコスト・性能の両面でSnowflakeを上回ります。Snowflake Enterprise Edition($3/クレジット)にアップグレードすると、一部のシナリオではDatabricksの方が安くなります。繰り返しになりますが、ベンチマークはあくまでベンチマークです。ぜひご自身のデータでも試してみてください。
Jeffはデータ・アナリティクス分野のコンサルタントで、インサイトの自動化やデータを活用したビジネスプロセス制御の領域で15年以上の経験を持ちます。技術面ではSnowflake + dbt + Tableauを得意とし、業務領域では公共事業、臨床試験、出版、CPG、製造業での経験があります。お気軽にご連絡ください:[email protected]。