
2026/01/22 2:03
**ジョイン最適化における課題**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
StarRocksはデータを正規化したまま保持し、コストベースのオプティマイザーを使用してジョインをオン・ザ・フライで最適化します。
- 論理的最適化ステップ:
• ジョイントランスフォーメーションルール – 厳密な予測子が存在する場合、クロス、外部、または完全外部ジョインは内部ジョインやセミ/アンチジョインに書き換えられます。
• 予測子プッシュダウン – WHERE句は前方の段階へ押し下げられ、さらにジョイントランスフォーメーションをトリガーすることがあります。
• 予測子抽出 – 排他的な予測子は先行して結合されるために積集合範囲(例:IN、範囲フィルタ)へ変換されます。
• 等価導出 – ジョインの等価条件はジョインの反対側に値制約を推論します(外部/セミジョインの場合は一方向)。
• LIMITプッシュダウン – LIMIT句はクロス、外部、および完全外部ジョインを通じて押し下げられ、データ転送量を削減します。 - ジョイン再順序戦略 – 左深型、網羅的、貪欲(トップ10)、DPsub;オプティマイザーはコストモデルを使用します:
[ \text{cost}= \text{CPU}\times(\text{rowL}+\text{rowR}) + \text{Memory}\times\text{rowR} ] - 分散ジョイン計画 – シャッフル、ブロードキャスト、バケットシャッフル、共位置化、複製;計画はテーブルサイズ、配布キー、およびクラスター構成に基づいて選択されます。
- ランタイムフィルタ – グローバル最小/最大、IN、ブルームフィルタはハッシュジョイン中に右側のハッシュテーブルから作成され、左スキャンへ押し下げられ、早期に行を除外します。
Demandbase、NAVER、およびShopeeでの実際の導入事例では、StarRocksのオン・ザ・フライジョインが非正規化または事前集計アプローチを置き換えることで測定可能な高速化とストレージコスト削減が示されています。将来的な作業では型変換の改善、ランタイムフィルタ使用の拡張、および大規模クラスタージョイン戦略の強化により、さらに大きなワークロードをサポートします。
本文
公開日: 2026年1月20日 午後9:18:43
著者について
Seaven He – StarRocks コミッター、Celerdata エンジニア
StarRocks におけるジョイン最適化
OLAP の中でジョインは最も難しい部分です。多くのシステムではスケールで効率的に実行できず、チームはテーブルをワイド化(ストレージが 10 倍)してデノーマライズしたり、複雑なストリーム処理パイプラインを構築したり、遅くて高価なスキーマ進化に苦しんでいます。
StarRocks は逆のアプローチを取ります:データは正規化されたままで、ジョインを「その場で」実行できるほど高速にします。課題はプランです。分散システムではジョイン探索空間が巨大になり、良いプランは数桁速くなる可能性があります。
この深掘り記事では、StarRocks のコストベース最適化エンジンがそれを実現する方法を 4 部分にわたって説明します。
- ジョインの基礎と最適化上の課題
- 論理的ジョイン最適化 – 型変換、プリディケートプッシュダウン、抽出、等価導出、LIMIT プッシュダウン
- ジョイン再順序付け – exhaustive, greedy, DP, left‑deep 戦略
- 分散ジョイン計画 – MPP 実行、プラン生成、グローバル実行時フィルタ
NAVER、Demandbase、Shopee の実際のケーススタディでビジネス価値を示します。
1. ジョインの基礎と最適化上の課題
1.1 ジョイントイプ
| タイプ | 説明 |
|---|---|
| クロス | 左 × 右テーブルのカートesian積 |
| 外部(Full/Left/Right) | マッチしない行は NULL を返す |
| アンチ | 、 のようにマッチしない行のみ取得 |
| セミ | マッチした行だけを取得。マッチ側から重複が発生しない |
| インナー | 左右テーブルの共通部分(1 対多になる場合もある) |
1.2 課題
| # | 課題 |
|---|---|
| 1 | ジョインアルゴリズムはシナリオごとに性能が異なる(Sort‑Merge vs Hash Join)。最適戦略を選択する必要がある。 |
| 2 | ジョイン順序の選択 – 左深木では可能な順序 ≈ 2ⁿ⁻¹、ブッシュリツリーではさらに多い(≈ 2ⁿ⁻¹ × C(n‑1))。探索コストは指数的に増大。 |
| 3 | ジョインの効果を推定することが難しい。1 対多関係やジョイン後フィルタは選択性推定を低下させる。 |
| 4 | 単一ノードで最適なプランでも、データ分布・シャッフリング・ネットワークコストを無視しているため、分散環境では非最適になることがある。 |
1.3 SQL 最適化フロー
StarRocks のオプティマイザは 2 段階で処理します。
- リライト – 論理変換(型変更、プリディケートプッシュダウン等)
- 最適化 – コストベースのプラン選択
1.4 ジョイン最適化の原則
- 高性能ジョイントイプを優先。ランキング: Semi/Anti > Inner > Outer > Full Outer > Cross。
- 小さい入力にハッシュテーブルを構築。
- 多重ジョインチェーンでは選択性が高いジョインを先に実行。
- ジョインに参加するデータ量を最小化。
- 分散ジョインでのネットワークオーバーヘッドを削減。
2. 論理的ジョイン最適化
2.1 型変換
3 つの主要ルールがあります。
| ルール | 発生条件・処理 |
|---|---|
| Cross → Inner | テーブル間に結合述語が存在する場合。例: を に変換。 |
| Outer → Inner | 左/右外部ジョインで、nullable 側を参照する strict(NULL を除外)述語がある場合。例: → inner join + 同じ where 節。 |
| Full → Left/Right | strict 述語で片側だけに絞り込める場合。例: → left outer join。 |
Strict 述語 は NULL を除外するもの(例:
a > 0)。StarRocks は参照列をすべて NULL に置き換えて式を簡略化し、strictness を判定します。
2.2 プリディケートプッシュダウン
WHERE 節のプリディケートを最も早いスキャンノードへ下げ、型変換を可能にする。
- WHERE: 1 つのジョイン入力に結び付く場合に推移可。
- ON‑clause: 内部 vs 外部/セミ/アンチでルールが異なる(詳細は各ケース参照)。
例:
SELECT * FROM t1 LEFT JOIN t2 ON t1.v1 = t2.v1 LEFT JOIN t3 ON t2.v2 = t3.v2 WHERE t1.v1=1 AND t2.v1=2 AND t3.v2=3;
プッシュダウン後:
(t1 LEFT JOIN t2) INNER JOIN t3 → t1 INNER JOIN t2。
2.3 プリディケート抽出
disjunctive(OR)プリディケートを conjunctive(AND)集合に変換し、値範囲の union/intersection を行う。
例:
WHERE (t2.v1 = 2 AND t1.v2 = 3) OR (t2.v1 > 5 AND t1.v2 = 4)
抽出結果:
t2.v1 >= 2t1.v2 IN (3, 4)
これらを元のプリディケートに付加。
2.4 等価導出
結合等価条件から逆側への値範囲推論。
例:
WHERE t2.v1 = 2 AND t1.v2 = 3 OR t2.v1 > 5 AND t1.v2 = 4
抽出後:
t2.v1 >= 2, t1.v2 IN (3, 4)結合
t1.v1 = t2.v1 を利用して t1.v1 >= 2 を導出。
外部/セミジョインではセマンティクス保持のため一方向のみで推論を行う。
2.5 LIMIT プッシュダウン
JOIN の出力行数が安定する場合(例: Left Outer Join → 左入力へ)、LIMIT を子オペレータに下げる。
例:
SELECT * FROM t1 LEFT JOIN t2 ON t1.v1 = t2.v1 LIMIT 100;
変換後:
SELECT * FROM (SELECT * FROM t1 LIMIT 100) t LEFT JOIN t2 ON t.v1 = t2.v1 LIMIT 100;
Cross と Full Outer では両入力へ LIMIT をプッシュ。
3. ジョイン再順序付け
StarRocks は連続した Inner/Cross ジョインを Multi‑Join Node にまとめ、これを再順序付けの基本単位とします。
3.1 戦略
- ヒューリスティック(ルールベース)
- 左深木(探索空間を限定)
- ブッシュリツリー(完全探索: exhaustive, greedy, simulated annealing, DP, genetic algorithms)
実装戦略は Left‑Deep、Exhaustive、Greedy、DPsub。
3.2 Exhaustive
全ての順序を列挙。
- 結合可換性 – 順序を入れ替え、ジョイントイプを適切に調整。
- 結合連想性 –
を inner/cross vs semi で特殊処理。(A JOIN B) JOIN C → A JOIN (B JOIN C)
3.3 Greedy
各イテレーションで最良の 1 つではなく、上位 10 の候補プランを保持し、最終的に多様な近似最適解を生成。グローバル最適は保証できないが、良好な解の確率が高まる。
3.4 コストモデル
JoinCost = CPU × (Row(L) + Row(R)) + Memory × Row(R)
– 左右子から推定される出力行数。Row(L/R)- CPU は入力処理量、Memory は右側にハッシュテーブルを構築するためのメモリ。
プラン生成制限:
| テーブル数 | 戦略 |
|---|---|
| ≤ 4 | Exhaustive |
| 5–10 | Left‑Deep ×1 + Greedy ×10 + DP ×1(可換性も併用) |
| > 10 | Greedy ×11 + Left‑Deep |
統計情報が欠落している場合は単一の左深プランにフォールバック。
4. 分散ジョイン計画
StarRocks は MPP フレームワークで動作し、ジョインはノード間でシャッフルまたはブロードキャストを伴う。
4.1 基本的分散プラン
| プラン | 説明 |
|---|---|
| Shuffle Join | 両テーブルを結合キーで再シャッフル。 |
| Broadcast Join | 小さなテーブルを全ノードへブロードキャストし、大きいテーブルと結合。 |
| Bucket Shuffle Join | 大きいテーブルのバケットに合わせて小さいテーブルだけをシャッフル(同一結合キーが必要)。 |
| Colocate Join | 同じ colocate グループ内で、分布キーが一致すればシャッフル不要。 |
| Replicate Join | 実験的:両テーブルの全コピーを各ノードに持つ(稀に実用) |
4.2 プラン生成
- 分布要件はジョインオペレータから上位へ伝播。
- 入力が要件を満たさない場合、
(シャッフル)を挿入しEnforce
ノードでネットワーク転送。Exchange
4.3 複合ジョイン
≥ 3 テーブルのクエリでは、全ジョインペアに対して shuffle と broadcast を組み合わせた豊富なプランセットを導出。Colocate や bucket shuffle オプションでさらに拡張。
4.4 グローバル実行時フィルタ
ハッシュジョイン中:
- 右側からハッシュテーブル構築。
- 観測データから Min/Max、IN、Bloom フィルタを生成。
- 左側のスキャンノードへフィルタをプッシュし、左側データ読み込み前に除外。
この早期フィルタリングにより、左側データ処理量が劇的に削減される。
要約
StarRocks のジョインオプティマイザは以下の原則を遵守しています。
- 高性能ジョイントイプを優先し、高価なものを回避。
- 小さい入力にハッシュテーブルを構築。
- 高選択性ジョインを最初に実行。
- 早期プリディケート・LIMIT プッシュダウンでデータ量を削減。
- 分散実行時はネットワークオーバーヘッドを最小化。
ケーススタディ
| 企業 | ハイライト |
|---|---|
| Demandbase | ClickHouse クラスターから移行し、性能向上とコスト削減を達成。 |
| NAVER | デノーマライズせずにマルチテーブルジョインでスケーラブルなリアルタイム分析を実現。 |
| Shopee | 外部 Hive データに対し Presto と比べ 3×–10× の性能向上、CPU 使用率約 60% 削減。 |
さらに詳細やご質問があれば、StarRocks Slack コミュニティへ参加してください。