すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB for SelectDB:バケットシャッフル結合の使用

最終更新日:Jan 16, 2025

このトピックでは、 でバケットシャッフル結合を使用してクエリを最適化する方法について説明します。 これにより、ノード間でデータを送信するために消費される時間と結合クエリのメモリオーバーヘッドが削減され、クエリのパフォーマンスが向上します。ApsaraDB for SelectDB

概要

バケットシャッフル結合は、特定の結合クエリに対してローカル最適化を提供し、ノード間でのデータ送信時間を短縮し、クエリを高速化します。 バケットシャッフル結合の設計、実装、および効果については、ISSUE 4394 を参照してください。

用語

  • 左テーブル: 結合クエリにおける左側のテーブル。 結合の並べ替えを使用して、プローブ操作を実行してテーブルの順序を変更できます。

  • 右テーブル: 結合クエリにおける右側のテーブル。 結合の並べ替えを使用して、ビルド操作を実行してテーブルの順序を変更できます。

仕組み

ApsaraDB for SelectDB でサポートされている一般的な分散結合実行方式には、シャッフル結合とブロードキャスト結合があります。 これら 2 つの結合実行方式は、高いネットワークオーバーヘッドを発生させます。

たとえば、テーブル A とテーブル B の間で結合クエリが実行され、ハッシュ結合アルゴリズムが使用されるとします。 クエリのオーバーヘッドは、結合実行方式によって異なります。 次のセクションでは、結合実行方式の種類について説明します。

  • ブロードキャスト結合: データがテーブル A の 3 つの HashJoinNodes に分散されている場合、テーブル B の全データを 3 つの HashJoinNodes に送信する必要があります。 この場合、クエリのネットワークオーバーヘッドとメモリオーバーヘッドは、テーブル B のデータ量の 3 倍になります。

  • シャッフル結合: シャッフル結合は、テーブル A とテーブル B のデータをハッシュし、クラスタノード間でデータを分散します。 この場合、クエリのネットワークオーバーヘッドは テーブル A とテーブル B のデータ量の合計 であり、クエリのメモリオーバーヘッドはテーブル B のデータ量です。

フロントエンド (FE) ノードは、各 ApsaraDB for SelectDB テーブルのデータ分散情報を格納します。 結合ステートメントがテーブルのデータ分散列にヒットした場合、バケットシャッフル結合は、データ分散情報に基づいて結合ステートメントによって生成されるネットワークオーバーヘッドとメモリオーバーヘッドを削減します。

image.png

前の図は、バケットシャッフル結合の仕組みを示しています。 テーブル A とテーブル B の間で結合クエリが実行され、結合クエリの等価式がテーブル A のデータ分散列にヒットします。 この場合、バケットシャッフル結合は、テーブル A のデータ分散情報に基づいて、テーブル B のデータをテーブル A のストレージノードに送信します。 バケットシャッフル結合は、次のオーバーヘッドを生成します。

  • ネットワークオーバーヘッド: テーブル B のデータ量。 このオーバーヘッドは、一般的な結合実行方式によって生成されるネットワークオーバーヘッドよりも少なくなります。 ブロードキャスト結合によって生成されるネットワークオーバーヘッドは テーブル B のデータ量の 3 倍 であり、シャッフル結合によって生成されるネットワークオーバーヘッドは テーブル A とテーブル B のデータ量の合計 です。

  • メモリオーバーヘッド: テーブル B のデータ量。 このオーバーヘッドは、一般的な結合実行方式によって生成されるメモリオーバーヘッドよりも少なくなります。 ブロードキャスト結合によって生成されるメモリオーバーヘッドは テーブル B のデータ量の 3 倍 であり、シャッフル結合によって生成されるメモリオーバーヘッドは テーブル A とテーブル B のデータ量の合計 です。

ブロードキャスト結合とシャッフル結合と比較して、バケットシャッフル結合はクエリのパフォーマンスを向上させ、ノード間でデータを送信するために消費される時間とクエリのメモリオーバーヘッドを削減します。 ApsaraDB for SelectDB の元の結合実行方式と比較して、バケットシャッフル結合には次の利点があります。

  • バケットシャッフル結合は、結合クエリのネットワークオーバーヘッドとメモリオーバーヘッドを削減して、クエリのパフォーマンスを向上させます。特に、FE ノードが左テーブルでパーティションプルーニングとバケットプルーニングを実行できる場合に効果的です。

  • バケットシャッフル結合は、コロケート結合とは異なります。 バケットシャッフル結合を使用する場合、テーブルのデータ分散情報を把握したり、対応する変更を加えたりする必要はありません。 バケットシャッフル結合には、テーブルのデータ分散に関する必須要件はありません。 これにより、データの偏りの問題を防ぎます。

  • バケットシャッフル結合は、結合の並べ替えにより多くの最適化方向を提供します。

使用方法

セッション変数を指定する

enable_bucket_shuffle_join セッション変数を true に設定します。 FE ノードは、結合実行方式をバケットシャッフル結合に変換できるクエリを自動的に計画します。

set enable_bucket_shuffle_join = true;

FE ノードが分散クエリを計画する場合、結合実行方式は コロケート結合 > バケットシャッフル結合 > ブロードキャスト結合 > シャッフル結合 という優先順位に基づいて選択されます。 ただし、ヒントを使用して結合実行方式を指定した場合、上記の優先順位は適用されず、指定された結合実行方式が使用されます。 例:

SELECT * FROM test JOIN [shuffle] baseall ON test.k1 = baseall.k1;

結合実行方式を表示する

explain コマンドを実行して、結合クエリがバケットシャッフル結合を使用しているかどうかを確認できます。

|   2:HASH JOIN                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
|   |  join op: INNER JOIN (BUCKET_SHUFFLE)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
|   |  hash predicates:                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
|   |  colocate: false, reason: table not in the same group                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
|   |  equal join conjunct: `test`.`k1` = `baseall`.`k1`                                         

BUCKET_SHUFFLE は、結合実行方式がバケットシャッフル結合であることを示します。

バケットシャッフル結合の計画ルール

ほとんどの場合、バケットシャッフル結合を使用してクエリのパフォーマンスを向上させるには、データ分散情報に基づいて変更を加えることなく、セッション変数を true に設定するだけで済みます。 ただし、バケットシャッフル結合の計画ルールに精通している場合は、より効率的な方法で SQL ステートメントを作成できます。

  • バケットシャッフル結合は、等価結合条件が使用されている場合にのみ有効になります。 これは、バケットシャッフル結合とコロケーション結合がハッシュ計算に基づいてデータ分散を決定するためです。

  • 等価結合条件には、2 つのテーブルのバケット列が含まれています。 左テーブルのバケット列が等価結合条件にある場合、クエリにバケットシャッフル結合が使用される可能性があります。

  • 計算されるハッシュ値はデータ型によって異なります。 したがって、左テーブルのバケット列のデータ型は、右テーブルのバケット列のデータ型と同じである必要があります。 等価結合条件にある 2 つのテーブルのバケット列のデータ型が異なる場合、計画を実行できません。

  • バケットシャッフル結合は、ApsaraDB for SelectDB のネイティブであるオンライン分析処理 (OLAP) テーブルにのみ適用されます。 Open Database Connectivity (ODBC)、MySQL、Elasticsearch テーブルなどの外部テーブルが左テーブルとして使用されている場合、計画を実行できません。

  • パーティションテーブルの場合、各パーティションのデータ分散ルールが異なる場合があります。 バケットシャッフル結合は、左テーブルにパーティションが 1 つだけ含まれている場合に有効になります。 したがって、SQL ステートメントを実行する際には、where 条件を使用して、パーティションプルーニングポリシーが有効になるようにする必要があります。

  • 左テーブルがコロケートテーブルの場合、各パーティションのデータ分散ルールは明確です。 この場合、バケットシャッフル結合はコロケートテーブルでより効果的に機能します。