等価結合(Equi-Join)は常に優れているのか?

「INNER JOIN(等価結合)は常にLEFT JOINより優れている」という通説は本当か?Snowflake上で3000万行のデータセットを用いたベンチマーク検証結果を解説。

等価結合(Equi-Join)は常に優れているのか?

データベースの内部動作や最適なクエリ記述方法についての主張や推奨事項を目にすることがあります。特に理論的な根拠が添えられているものは興味深く、さらに理論の予測を裏付ける検証テストや、再現可能なスクリプトが公開されているものは格別の価値があります。

しかし現実には、「パターンXは常にパターンYより高性能である」といった性能に関する主張が、検証なしに一般論として語られることが少なくありません。業務データの特性を熟知している場合や明確な数学的証明がある場合は別ですが、インデックスや結合戦略に関する多くの主張は、特定のデータベース技術やバージョンに限定して捉えるべきです。検証のない言説を鵜呑みにせず、実際にテストして確かめる必要があります。

SQL Server 2008での検証結果をSQL Server 2019と比較すれば、エンジンの進化により全く異なる挙動を示します。また、PostgreSQLとSnowflakeやExasolを比較すれば、後者は分析クエリに特化して設計されているため、最適化の振る舞いも大きく異なります。

だからこそ、筆者は以下の通説に疑問を投げかけたいと思います:

「等価結合(INNER JOIN)は、LEFT JOIN(外部結合)より常に優れている」

なぜこれが重要なのか

特定のパターンを盲目的に適用すると、深刻なパフォーマンス低下を招く恐れがあります。DWH自動化スイート「Datavault Builder」を開発する私たちにとって、パターンの選択ミスは何百、何千倍ものクエリへと増幅されてしまうからです。

なぜLEFT JOINの方が優れている場合があるのか

もちろん、INNER JOINが優れている条件下も多々あります。例えば、クエリオプティマイザが結合チェーンの両端のどちらからでも探索を開始でき、中間結果セットを劇的に絞り込んだ上で、インデックスの効いた大規模テーブルへのわずかなルックアップで済ませられる場合などです。

しかし、それが常に当てはまるわけではありません。以下の2つのシナリオを考えてみましょう:

シナリオ1:

10個のテーブルがあります。1つは1,500万件のテーブル、残りの9個はそれぞれ4,500万件のテーブルです。すべての結合は1,500万件のテーブルから周囲のテーブルへと向かっています。1,500万件すべてのレコードが、9つのテーブルすべてに一致するエントリを持っています。

  • INNER JOIN を実行
  • LEFT JOIN を実行

シナリオ2:

10個のテーブルがあります。1つは3,000万件のテーブル、残りの9個はそれぞれ4,500万件のテーブルです。すべての結合は3,000万件のテーブルから周囲のテーブルへと向かっています。1,500万件は一致するエントリを持ち、残りの1,500万件は一致しません。

  • INNER JOIN を実行(一致しない1,500万件の欠落を防ぐため、9つのテーブルにダミーレコードを事前に登録しておく必要があります)
  • LEFT JOIN を実行

テスト構成:4,500万件のサテライト9テーブルに結合される3,000万件テーブル — Snowflakeにおける等価結合ベンチマーク

これは筆者が2021年8月26日にSnowflake上で実際に実行したテスト構成です。

筆者の仮説は、「この種のクエリではLEFT JOINの方が高速である」というものでした。2年前にSQL Server(2017)とOracle(12c)で同様のテストを実施した際にも、このシナリオではLEFT JOINの方が優れたパフォーマンスを示したためです。

理論的な背景として、少なくともシナリオ2においては、結合前に3,000万件のテーブルをフィルタリングできるため、処理効率が高まると考えられます。全件一致するシナリオ1でも同等か、わずかに数パーセント遅い程度にとどまると予想されました。

さらに、LEFT JOINを使用する場合、他テーブルに一致レコードが存在しないことを示すために単に「NULL」を扱えばよいため、INNER JOIN用にダミーレコード用のカラムやターゲット行を保持する方式と比べてディスク容量を大幅に削減できます。

ディスク容量の比較:LEFT JOIN vs INNER JOINのテーブル準備(1カラムおよび2カラムのサロゲートキー方式) 3,000万件ロード時の実測値:INNER JOIN用の準備テーブルは50%〜5倍のディスク容量を消費

ベンチマークテストの実施

Snowflakeの結果キャッシュ(Result Cache)は無効化して計測しました。各テストは最低3回実行し、実行間のブレが10%未満のものを採用しました。

検証結果

1500万/3000万件のテーブルと他の9テーブルとの結合において、「2カラムで結合」する場合と「サロゲートキーで1カラムに統合して結合」する場合の2通りをテストしました。

Snowflake上での本データ量において、LEFT JOIN版のパフォーマンスはINNER JOIN版と同等、またはより高速でした。

ベンチマーク実行1:SnowflakeにおけるLEFT JOINとINNER JOINの実行時間比較

クロス結合のクエリ結果:一致および不一致レコードの分布

ベンチマーク実行2:サテライト間結合の実行時間 — LEFT JOIN vs INNER JOIN

ベンチマーク実行3:LEFT JOINの優位性を裏付ける実行時間

公平を期すために補足すると、1カラムのINNER JOINはスキャンするデータ量が20〜25%少なくなります(フィルタリングが不要なため)。しかし、これはローカルスキャンであるため大きなペナルティにはならず、JOIN自体の処理速度が上回るため問題ありませんでした。

また当然ながら、1カラムでの結合は2カラムでの結合に比べて圧倒的に効率的であることが確認されました。

3サテライトにわたる性能比較:1カラムサロゲートキーが2カラム結合を圧倒 — Snowflake Sサイズウェアハウス

まとめ

特定のケースにおいてINNER JOINがLEFT JOINより優れたパフォーマンスを発揮するのは事実です。しかし、それがすべてではありません。適切な条件下では、LEFT JOINはINNER JOINと同等か、むしろ大幅に高速に動作することが再現可能なテストによって実証されました。

「INNER JOINが常に良い」という固定観念にとらわれず、利用するデータベース技術やバージョン、クエリパターンに合わせて実測・検証することが極めて重要です。

また、Snowflakeにおいては結合キーを1カラムに集約することが極めて高い効果をもたらします。


貴社のデータ基盤にDatavault Builderがどのように適合するかを確認してみませんか?無料の個別デモを予約する — 専任のスペシャリストが具体的なユースケースに合わせてご案内します。