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

PolarDB:GroupJoinを使用したIMCI対応操作の実行

最終更新日:May 24, 2024

このトピックでは、GroupJoinを使用してPolarDBデータベースでIMCI対応操作を実行するための制限と方法について説明し、GroupJoinに関連する論文を紹介します。 このトピックを読む前に、HASH JOINとHASH GROUP BYについて理解しておくことをお勧めします。

背景情報

SELECT
  key1,
  SUM(sales) as total_sales
から
  fact_table LEFT JOIN dimension_table ON fact_table.key1 = dimension_table.key1
グループ化
  fact_table.key1
注文によって
  total_sales
LIMIT 100; 

従来、PolarDBデータベースで上記のIMCI対応クエリを実行する場合は、HASH JOINを実行してからHASH GROUP BYを実行する必要があります。 HASH JOINとHASH GROUP BYの両方で、key1を使用してハッシュテーブルを作成します。 以下の段落では、key1の使用方法について説明します。 fact_table.key1はdimension_table.key1と同じであることに注意してください。

  1. HASH JOIN: dimension_table.key1を使用してハッシュテーブルを作成し、fact_table.key1を使用してハッシュテーブルと出力データを照会します。

  2. HASH GROUP BY: fact_table.key1を使用して別のハッシュテーブルを作成し、この新しいテーブルのデータを集約します。

効率を向上させるために、HASH JOINとHASH GROUP BYの実行を1つの演算子に統合する方法が必要です。 演算子は、dimension_table.key1を使用してハッシュテーブルと集計データを作成し、fact_table.key1を使用してテーブルと集計データを照会します。 この演算子が使用される場合、別のハッシュテーブルを作成する必要はありません。 この考えに従って、GroupJoin演算子が導入される。

GroupJoinは、別のハッシュテーブルを作成する手間を省き、中間結果のデータサイズを削減します、JOIN演算は、多数の結果を含む結果セットを生成してもよい。 これは、テーブルの行が別のテーブルの複数の行と一致する可能性があるためです。 最悪の場合、N行テーブルとM行テーブルとの結合結果は、N × M行の結果を含む結果セットである。 HASH JOINとHASH GROUP BYを順に実行すると、N行のハッシュテーブルが作成され、N × M × S行のデータが出力され、データ集約用の新しいハッシュテーブルが作成されます。 この手順は、リソースの無駄を引き起こす可能性があります。 データ列を計算するための式において、Sは選択性を示し、0〜1の値であり得る。 上記のコードでは、LEFT OUTER JOINはM行のファクトテーブル (大きなテーブル) とN行のディメンションテーブル (小さなテーブル) に対して実行され、key1は一意のキーです。 この場合、N行のハッシュテーブルが生成され、M行のデータが出力され、次に、M行の集約データを含む別のハッシュテーブルが作成される。 ただし、GroupJoinが同じ2つのテーブルで実行される場合、データは結合され、N行ハッシュテーブルの両方に集約されます。 これにより、時間と消費するメモリリソースが少なくなります。

GroupJoinの利点を活用するために、PolarDB for MySQLでは、GroupJoin for IMCI対応操作が提供されています。

仕組み

概要

IMCI対応操作では、GroupJoinは、HASH JOINとHASH GROUP BYの組み合わせ実行として実行されます。

  1. GroupJoinが実行されると、小さい左側のテーブルが最初に使用されてハッシュテーブルが作成されます。 左側のテーブルのデータはハッシュテーブルの作成時に集計され、HashGroupby left_tableと同じ効果が得られます。

  2. 次に、作成されたハッシュテーブルのデータを照合するために、大きな右側のテーブルが使用される。 一致条件を満たすデータはハッシュテーブルに集約され、一致条件を満たさないデータは省略されます。 この集計は、右側のテーブルに関連するデータの集計と見なされます。

このセクションでは、GroupJoinの概要を説明します。 以下のセクションは詳細を提供する。

制限

GroupJoinの実行の複雑さを軽減するために、PolarDB for MySQLは実行に次の制限を設定します。

  1. GROUP BYキーは、片側で使用される結合キーと同じである必要があります。 場合によっては、GROUP BYキーは、結合キーの一部のみに機能的に依存する。

  2. RIGHT JOIN + GROUP BY RIGHTのシナリオでは、正しいキーは一意でなければなりません。 そうしないと、操作をLEFT JOINまたはGROUP BY LEFTに変更するか、GroupJoinを使用できません。

  3. aggr関数は、左側のテーブルまたは右側のテーブルのみを一度に参照できます。 SUN(t1.a + t2.a) の場合のように、GROUP BY演算子のaggr関数が両方のテーブルを同時に参照する場合、GroupJoinは適用されません。

サンプルコード

INNER JOIN/GROUP BY LEFT

サンプルコード:

l_table INNER JOIN r_table
ON l_table.key1 = r_table.key1
グループBY l_table.key1 
説明

以下の説明は、以下の前提に基づいて説明する。・SQL文が上記のように順番に実行され、JOIN操作のオブジェクトが動的に別のテーブルに切り替えられないこと。

  1. 左側のテーブルを使用してハッシュテーブルを作成します。 ハッシュテーブルが作成されると、aggr関数が実行され、左側のテーブルのデータが集計されます。 aggr関数が右側のテーブルのデータを集約するために実行されるとき、反復カウントがハッシュテーブルエントリのペイロードの数をカウントするために使用される。

  2. テーブルが結合されると、右側のテーブルを使用してハッシュテーブルのエントリを照合します。 右側のテーブルの行に一致するエントリがない場合、その行は省略されます。 1つのエントリが一致する場合、左側のテーブルのaggrコンテキストの繰り返しカウントにスコア1が追加され、右側のテーブルのaggr関数が実行されます。

  3. JOINが実行された後、一致したハッシュテーブルエントリのみの集計結果が出力され、一致しないハッシュテーブルエントリは省略されます。

  4. 集計結果は、SUM(expr) に繰り返しカウントを掛けた結果に等しい。 例えば、SUM(expr) の結果が200であり、繰り返し回数が5である場合、集計結果は1000となる。

INNER JOIN/GROUP BY RIGHT

サンプルコード:

l_table INNER JOIN r_table
ON l_table.key1 = r_table.key1
グループBY r_table.key1 

l_table.key1はr_table.key1と同じであるため、サンプルコードではINNER JOINとGROUP BY LEFTのシナリオについて説明します。

LEFT OUTER JOIN/GROUP BY LEFT

サンプルコード:

l_table LEFT OUTER JOIN r_table
ON l_table.key1 = r_table.key1
グループBY l_table.key1 
  1. 左側のテーブルを使用してハッシュテーブルを作成します。 ハッシュテーブルが作成されると、aggr関数が実行され、左側のテーブルのデータが集計されます。 右側のテーブルのデータが集計されている場合は、繰り返し回数を使用します。

  2. テーブルが結合されると、右側のテーブルを使用してハッシュテーブルのエントリを照合します。 右側のテーブルの行に一致するエントリがない場合、その行は省略されます。 1つのエントリが一致する場合、左側のテーブルのaggrコンテキストの繰り返しカウントにスコア1が追加され、右側のテーブルのaggr関数が実行されます。

  3. このシナリオは、INNER JOINとは次の点で異なります。JOINが実行された後、ハッシュテーブルの一致しないエントリは別のグループにリストされ、右側のテーブルの対応するaggr関数の入力はすべてNULLになります。

左外側の参加 /グループバイ右

サンプルコード:

l_table LEFT OUTER JOIN r_table
ON l_table.key1 = r_table.key1
グループBY r_table.key1 
  1. 左側のテーブルを使用してハッシュテーブルを作成します。 ハッシュテーブルが作成されると、aggr関数が実行され、左側のテーブルのデータが集計されます。 aggr関数を実行して右側のテーブルのデータを集計する場合、繰り返しカウントが使用されます。

  2. テーブルが結合されると、右側のテーブルを使用してハッシュテーブルのエントリを照合します。 右側のテーブルの行に一致するエントリがない場合、その行は省略されます。 1つのエントリが一致する場合、左側のテーブルのaggrコンテキストの繰り返しカウントにスコア1が追加され、右側のテーブルのaggr関数が実行されます。

  3. JOINが実行された後、ハッシュテーブルの一致したエントリが出力され、一致しなかったエントリは別のグループにリストされ、右側のテーブルの対応するaggr関数の入力はすべてNULLになります。

右外側の参加 /グループごとに左

サンプルコード:

l_table右外側JOIN r_table
ON l_table.key1 = r_table.key1
グループBY l_table.key1 
  1. 左側のテーブルを使用してハッシュテーブルを作成します。 ハッシュテーブルが作成されると、aggr関数が実行され、左側のテーブルのデータが集計されます。 aggr関数を実行して右側のテーブルのデータを集計する場合、繰り返しカウントが使用されます。

  2. テーブルが結合されると、右側のテーブルを使用してハッシュテーブルのエントリを照合します。 エントリが右側のテーブルの行と一致する場合、左側のテーブルのaggrコンテキストの繰り返し回数にスコア1が加算され、右側のテーブルの集計結果が計算されます。 一致するエントリがない場合、すべて右側のテーブルの一致しない行は別のグループにリストされ、左側のテーブルの対応する集計結果はすべてNULLになります。

  3. JOINが実行された後、ハッシュテーブル内の一致したエントリが出力され、一致しないエントリは省略されます。

右外側の参加 /グループバイ右

サンプルコード:

l_table右外側JOIN r_table
ON l_table.key1 = r_table.key1
グループBY r_table.key1 

制限

r_table.key1は一意である必要があります。 それ以外の場合、結合操作は無効です。 r_table.key1が一意かどうかわからない場合は、オプティマイザを使用してJOINをLEFT OUTER JOINに変換し、GROUP BYをGROUP BY LEFTに変換します。

手順

  1. 左側のテーブルを使用してハッシュテーブルを作成します。 ハッシュテーブルが作成されると、aggr関数が実行され、左側のテーブルのデータが集計されます。 右側のテーブルのデータが集計されている場合は、繰り返し回数を使用します。

  2. テーブルが結合されると、右側のテーブルを使用してハッシュテーブルのエントリを照合します。 右側のテーブルの行と一致する場合、左側のテーブルの集計結果と右側のテーブルの集計結果が出力されます。 一致するエントリがない場合、集計結果も出力されますが、左側のテーブルの集計結果はすべてNULLになります。

  3. JOINが実行された後、GroupJoinは完了し、ハッシュテーブルエントリを管理する必要はない。

GroupJoinを使用した場合のデータの流出

GroupJoinが実行されると、HASH JOINおよびHASH GROUP BYのパーティションスタイルの実行のためのデータスピルと同じ方法でデータがスピルされます。 以下の点で詳細を説明します。

  1. GroupJoinアルゴリズムは、パーティションスタイルを使用します。

  2. 左側のテーブルを使用してハッシュテーブルを作成する場合、一部のデータパーティションはメモリに格納されます。 ハッシュテーブルを作成するためのステートメントは、サンプルコードこのトピックのセクション。

  3. 他の一部のデータパーティションは、ディスク内の一時ファイルにこぼれます。 これらのパーティションに書き込まれた増分データも、対応するの一時ファイルにスピルされます。 これらのパーティションに対してブルームフィルタが作成され、右側のテーブルの一致しないデータを効率的に除外するのに役立ちます。

  4. ハッシュテーブルが作成されたら、右側のテーブルのデータを使用してハッシュテーブルのデータを照合します。

    1. クエリするデータパーティションがメモリに存在する場合、サンプルコードセクションのステートメントが実行されます。 データパーティションがメモリにない場合、ブルームフィルタを使用して、照会されたデータが指定されたパーティションにあるかどうかを確認します。 そうである場合、データは、パーティションに対応する一時ファイルにスピルされる。 いいえの場合、データは省略または出力されます。

    2. メモリ内のデータパーティションが照会された後、システムはディスク内のデータパーティションを順番に照会する。 この例では、少なくとも1つのデータパーティションをディスクに入れることができ、マイナーパーティションに分割する必要はありません。 次に、このトピックのサンプルコードセクションにあるステートメントを実行します。

関連論文

2011では、という名前の論文「Group-Byによるクエリの加速とGroupjoinによる参加」(以下、ペーパー1と呼ぶ) が公開されました。 このペーパーでは、さまざまなクエリでのGroupJoinの実現可能性を理論的な観点から説明しますが、GroupJoinの実装に関する十分な詳細は提供していません。 この論文では、GroupJoinの使用の制限と、さまざまなaggr関数を実行する必要がある場合など、GroupJoinが適用されるシナリオについて説明します。 論文の説明は比較的抽象的であり、理解するのは容易ではありません。

2021では、という名前の論文「グループ結合とネストされた集合体への実践的アプローチ」(以下、ペーパー_2と呼ぶ) が公開されました。 このペーパーでは、GroupJoinをインメモリデータベースに効率的に実装する方法について説明します。 このペーパーでは、次のハイライトを提供します。

1. サブクエリ分離のアルゴリズムでGroupJoinを使用する方法

image.png

GROUP BYなどのサブクエリが終了する場合は、MagicSetを使用してテーブルの重複を解消し、JOINとGROUP BYの組み合わせを追加して、相関するサブクエリを分離できます。 このシナリオでは、GroupJoinを使用できます。 同様のデカップリングアルゴリズムは、PolarDBのIMCI対応操作で使用されます。 ただし、子オブジェクトを共有するような実行プランは生成できません。

2。 熱心な集計を実行する方法

ハッシュテーブルが作成されると、各ハッシュテーブルエントリのペイロードを保持して後でデータを集約するのではなく、左側のテーブルのデータが集約されます。 熱心な集計は、PolarDBのIMCI対応操作でも実行できます。

3。 ハッシュテーブルエントリの同時クエリおよび集計中にメモを使用して規則を解決する方法

極端な場合、ハッシュプローブ中に、右側のテーブルのすべての行がハッシュテーブルの同じエントリに一致します。 この場合、そのエントリに対してSUM(2 × col) のようなアグリゲーションを実行しなければならず、aggrコンテキストはアグリゲーションにおいて繰り返し使用されなければならない。 例えば、SUM() が実行される場合、同じsum_valueを使用して値を繰り返し合計する。 演算性能は、一般的なaggr関数の使用は言うまでもなく、原子変数の加算演算においても競合によって制限される。 この制限を解決するために、本稿では解決策を紹介する。 CASコマンドは、オーナスレッドIDを設定するために各エントリに対して実行される。 スレッドがエントリを所有できない場合、計算を実行するためにローカルハッシュテーブルが作成されます。 次に、すべてのローカルテーブルの計算結果をグローバルハッシュテーブルに集約します。

4。 GroupJoinがすべてのシナリオに適用されない理由

一部のシナリオでは、JOINとGROUP BYの組み合わせがGroupJoinよりも適しています。 以下のケースは、例を提供する。左側の選択性は低く設定される。 ハッシュプローブが完了すると、左側のほとんどの行は選択されません。 したがって、ジレンマが発生します。

  • ハッシュテーブルが構築されるときに熱心な集計が実行される場合、ペイロードを保持する必要はありません。 これはメモリリソースを節約するのに役立ちますが、選択性が低いためにほとんどの行が選択されず、事前に実行された集約に無駄が生じます。

  • 事前に集約を行わない場合、メモリの使用により多くの時間を費やす必要があります。

したがって、選択性が低い場合、以下の方法が推奨される: JOINが完了した後、いくつかのグループが生成され、HASH BY GROUPを使用して局所凝集を行う。 このペーパーでは、さまざまなシナリオでこのメソッドを実装する方法について説明します。 特定のシナリオに適したクエリの種類を把握するには、選択性とカーディナリティを計算するオプティマイザが必要です。 このペーパーでは、オプティマイザで使用されるいくつかの計算方法も推奨します。

PolarDBのIMCI対応操作では、前述のジレンマは面倒ではありません。 これは次の理由によるものです。

  • PolarDBのIMCIが有効な操作では、通常、小さなテーブルを使用してハッシュテーブルを作成します。

  • 選択性が低く、熱心な集約が実行される場合、メモリリソースは、小さなテーブルで時間を浪費することを犠牲にしてのみ節約される。

したがって、前述のRIGHT JOINとGROUP BY RIGHTを使用するシナリオは別として、GroupJoinは常に、IMCI対応操作のHASH JOINとHASH GROUP BYの組み合わせよりも効率的です。PolarDB.

論文の著者とテストから判断すると、このトピックで言及されている2つの論文は、両方ともミュンヘンのルートヴィヒマクシミリアン大学のハイパーデータベースチームからのものです。 ハイパーデータベース以外に、GroupJoinを実装するために他の種類のデータベースは導入されていません。 しかし、「共有ハッシュテーブル」動作は、他の方法で実行することができ、これについては今後説明する。

GroupJoinをTPC-Hクエリで使用

TPC-Hは、APシステムの分析処理 (AP) 機能をテストするために一般的に使用されるベンチマークです。 GroupJoinは、TPC-Hの22のクエリの多くに適用されます。 ただし、TPC-H Q13を除き、他のクエリのステートメントを変更してGroupJoinに適したものにする必要があります。

Q13

GroupJoinはTPC-H Q13で直接使用できます。 Q13のサンプルコード:

select
    c_count,
    custdistとしてカウント (*)
から
    (
        選択
            c_custkey,
            count(o_orderkey) をc_countとして
        から
            customer
            c_custkey = o_custkeyの左外側結合注文
            そしてo_commentは '% pending % deposits %' のようではない
        グループによって
            c_custkey
    ) c_orders
グループによって
    c_count
による注文
    custdist desc,
    c_count desc; 
  • GroupJoinがIMCI対応操作で使用されない場合、次の実行プランが使用されます。

    image.png

  • GroupJoinがIMCI対応操作で使用される場合、次の実行プランが使用されます。

    image.png

Q3

GroupJoinをTPC-H Q3で使用するには、次の変更を行う必要があります。 Q3のサンプルコード:

select
    l_orderkey,
    sum(l_extendedprice * (1 - l_discount)) を収益として、
    o_orderdate,
    o_shippriority
から
    顧客、
    注文、
    lineitem
ここで
    c_mktsegment = 'BUILDING'
    とc_custkey = o_custkey
    とl_orderkey = o_orderkey
    およびo_orderdate < date '1995-03-15'
    およびl_shipdate > date '1995-03-15'
グループによって
    l_orderkey,
    o_orderdate,
    o_shippriority
による注文
    収益desc、
    o_orderdate
制限
    10; 

次のQ3の実行プランは、IMCIが有効な操作で使用できます。DERKEY、TEMPTABLE

image.png

このステートメントでは、グループ化キーはl_orderkey、o_orderdate、およびo_shippriorityです。 グループ化キーはすべての結合キーとは異なるため、GroupJoinは適用できません。 一連の控除の後、次の結論を引き出すことができます。

  1. INNER JOINは、lineitemテーブルと注文テーブルで実行されます。 JOIN述語はl_orderkey=o_orderkeyです。 したがって、JOIN操作の結果セットでは、l_orderkeyはo_orderkeyに等しくなります。

  2. l_orderkeyはo_orderkey、GROUP BY l_orderkey、o_orderdateに等しいため、o_shippriorityはGROUP BY o_orderkey、o_orderdate、o_shippriorityと同等です。

  3. o_orderkeyは注文テーブルの主キーであるため、o_orderdateとo_shippriorityは機能的に各o_orderkeyに依存します。

  4. 前の結論のため、GROUP BY o_orderkey、o_orderdate、o_shippriorityはGROUP BY o_orderkeyと同等です。

したがって、Q3のGROUP BY句をGROUP BY o_orderkeyに置き換えた後、GroupJoinを使用できます。 サンプルコード: KEY,TEMPTABLE3.SUM(LINETTEM.EXTENDEDPRTCE * 1.00-LUNETEM._DLSCOL

image.png

関数依存性に関する控除は、オプティマイザに要件をもたらします。 MySQLオプティマイザは、関数の依存関係ロジックの一部を差し引くのに役立ちますが、GROUP BY o_orderkeyを同等性として使用する結論を引き出すのには役立ちません。 SQL SERVERは、GROUP BY o_orderkeyの使用を差し引くのに役立ちます。これは理論的には十分に証明されていますが、IMCI対応のプラクティスでは完全には証明されていません。 これは、TPC-HのQ3、Q4、Q10、Q13、Q18、Q20、およびQ21についても同様である。 推論が完全に行われることができれば、GROUP BYのグループ化キーは短縮され、データ集約は高速化される。

Q10

GroupJoinはTPC-H Q10で直接使用できません。 Q10のサンプルコード:

select
    c_custkey,
    c_name,
    sum(l_extendedprice * (1 - l_discount)) を収益として、
    c_acctbal,
    n_name、
    c_address,
    c_phone,
    c_comment
から
    顧客、
    注文、
    lineitem,
    国家
ここで
    c_custkey = o_custkey
    とl_orderkey = o_orderkey
    およびo_orderdate >= date '1993-10-01'
    およびo_orderdate < date '1993-10-01 '+ interval '3' 月
    およびl_returnflag = 'R'
    およびc_nationkey = n_nationkey
グループによって
    c_custkey,
    c_name,
    c_acctbal,
    c_phone,
    n_name、
    c_address,
    c_comment
による注文
    収益desc
制限
    20; 

Q10でGroupJoinを使用する前に、次の変更を加える必要があります。

  1. グループ化キーを、顧客テーブルの主キーであるc_custkeyに置き換えます。 手順はQ3セクションの手順と同様です。

  2. 結合順序は、顧客テーブルのjoin操作が最外層になるように調整する必要があります。

最初の修正は常にプラスの効果がありますが、2番目の修正は時々副作用があります。

Q17

TPC-H Q17は相関サブクエリを含む。 Q17のサンプルコード:

select
    sum(l_extendedprice) / 7.0 as avg_yearly
から
    lineitem,
    部分
ここで
    p_partkey = l_partkey
    p_brand = 'Brand#44'
    p_container = 'WRAP PKG'
    and l_quantity < (
        選択
            0.2 * avg(l_quantity)
        から
            lineitem
        where
            l_partkey = p_partkey
    );

いくつかの方法を使用してサブクエリを分離できます。 次の2つの図は、IMCIが有効なシナリオでスカラーaggrの2つのデカップリングアルゴリズムに基づいて使用できる2つの実行プランを示しています。

image.pngRE

image.png

これらの実行プランは、GroupJoin演算子には適用されません。 MagicSetを使用してサブクエリを分離する場合、MagicSetを削除する前に中間状態を入力できます。 状態はGroupJoinに適しています。

image.png

このプロセスは、ペーパー_2の図3にも示されています。 NERALNESTING:DEEORRELATIONOFDEPENDENTSUB-

image.png

この場合、GroupJoinを使用することができる。 PolarDBは、IMCI対応シナリオでのデカップリング方法としてMagicSetを部分的にサポートしています。 子オブジェクトを共有する実行プランは生成できないため、サポートは完了していません。 したがって、IMCI対応シナリオでは、GroupJoinをTPC-H Q17に使用することはできません。

Q18

GroupJoinは、実行プランが変更された場合にのみ、TPC-H Q18で使用できます。 この例では、説明を簡略化し一般化するために、InサブクエリとORDER BY句を省略しています。 Q18のサンプルコード:

select
    c_name,
    c_custkey,
    o_orderkey,
    o_orderdate,
    o_totalprice、
    sum(l_quantity)
から
    顧客、
    注文、
    lineitem
ここで
    c_custkey = o_custkey
    とo_orderkey = l_orderkey
グループによって
    c_name,
    c_custkey,
    o_orderkey,
    o_orderdate,
    o_totalprice 

TPC-H Q18の場合、次の変更を加えることができます。

  1. c_custkeyは顧客テーブルの主キーであるため、c_nameはc_custkeyに機能的に依存します。 同様に、o_orderkeyは注文テーブルの主キーであるため、o_orderdateとo_totalpriceはo_orderkeyに機能的に依存できます。 したがって、Q18のGROUP BY句は、GROUP BY c_custkey、o_orderkeyに同等に変換できます。

  2. 顧客テーブルと注文テーブルのJOIN述語はc_custkey=o_custkeyであるため、結合結果はc_custkeyがo_custkeyに等しい行になります。

  3. c_custkeyはo_custkeyに等しいため、GROUP BY句はGROUP BY o_custkey、o_orderkeyに同等に変換できます。

  4. o_orderkeyはo_custkey、GROUP BY o_custkeyに一意に対応するため、o_orderkeyはGROUP BY o_orderkeyに変換できます。

次のサンプルコードは、変更後のクエリの例を示しています。

select
    ANY_VALUE(c_name) 、
    ANY_VALUE(c_custkey) 、
    o_orderkey,
    ANY_VALUE(o_orderdate) 、
    ANY_VALUE(o_totalprice) 、
    sum(l_quantity)
から
    顧客、
    注文、
    lineitem
ここで
    c_custkey = o_custkey
    とo_orderkey = l_orderkey
グループによって
    o_orderkey 
  • GroupJoinが使用されない場合、次の実行が使用されます。

    image.png

  • GroupJoinが使用されている場合、次の実行が使用されます。

    image.png

修正されたクエリは、GROUP BYのグループ化キーが短縮されるため、通常の実行計画を作成するために使用できます。

Q20

TPC-H Q20における相関サブクエリは、Q17におけるものと同様である。 MagicSetは、サブクエリを分離するために使用されます。 MagicSetが除去される前に、GroupJoinに適した中間状態が入力される。

select
...
およびps_availqty > (
    選択
        0.5 * sum(l_quantity) < ! --- スカラーaggr --->
    から
        lineitem
    where
        l_partkey = ps_partkey < ! --- 相関アイテム1 --->
        とl_suppkey = ps_suppkey < ! --- 相関アイテム2 --->
        およびl_shipdate >= '1993-01-01'
        とl_shipdate < date_add('1993-01-01 '、間隔 '1' 年)
) 

その他のクエリ

、paper_1およびpaper_2によれば、GroupJoinは、クエリが変更された後、Q5、Q9、Q16、およびQ21で使用できます。 ただし、4つのクエリの修正方法は、論文には記載されていません。 GroupJoinの実行計画は、ハイパーデータベースチームのHyPer WebInterface Webページでも提供されていません (https:// hyper-db.de/interface.html# ) 。

Queryのパフォーマンス

多くのTPC-HクエリにはJOINとGROUP BYが含まれます。 このようなクエリは、GroupJoinを使用して最適化できます。 paper_1では、Q3、Q5、Q9、Q10、Q13、Q16、Q17、Q20、およびQ21のクエリでGroupJoinを使用する前後のクエリのパフォーマンスを比較します。

image.png

比較では、1GBのデータが使用されます。 一般に、TPC-Hクエリのレイテンシは、GroupJoinが使用された後、1,932 msから1,295 msに短縮されます。

paper_2では、著者は1 GBのデータを使用して、Q3、Q13、Q17、およびQ18でGroupJoinを使用する前後のクエリのパフォーマンスを比較します。

image.png

次の情報は、上記の折れ線グラフの線の意味を示しています。

  1. 別の行は、JOINとGROUP BYが使用されるシナリオを表します。

  2. イーガーラインは、イーガーアグリゲーションが実行されるシナリオを表す。

  3. メモ線は、メモを最適化に使用するシナリオを表します。これについては、前のセクションで説明します。 折れ線グラフは、Q3、Q13、Q17、およびQ18の次の現象を示しています。

    1. メモを使用した後のクエリのパフォーマンスは、HASH JOINおよびHASH GROUP BYを使用した場合のパフォーマンスと同様です。

    2. Eager集計は、Q13のみで最高のクエリパフォーマンスを提供します。

折れ線グラフは、クエリ方法のパフォーマンスがクエリシナリオによって異なることを証明しています。 これは、GroupJoinの最適な実行プランを選択するには、オプティマイザに統計を提供する必要があるという論文の考え方と一致します。 論文によると、オプティマイザはGroupJoinと対応するアルゴリズムが適切に使用されるようにするのに役立ちます。

しかし、専門家のPolarDB次の面で論文のアイデアに同意しません:

  1. この論文では、スループット (タプル /s) を使用してアルゴリズムの品質を測定します。 このインジケータは、IMCIが有効なシナリオのPolarDBの実験でも使用されますが、結果は異なります。 次の表に、Q3、Q13、およびQ18のGroupJoinのスループットを示します。

    クエリ

    HASH JOIN + HASH GROUP BY

    GroupJoin

    Q3

    130 MB

    152 MB

    Q13

    11 MB

    33 MB

    Q18

    315 MB

    1 GB

    説明

    IMCIが有効なシナリオでは、GroupJoinはQ17には適用されません。

    紙とPolarDBの実験で使用されるデータの量は同じですが、各クエリのスループットは2つの実験で異なります。 これは、実装方法の違いによって引き起こされる可能性があります。 PolarDBの実験は、GroupJoinがRIGHT JOINとGROUP BY RIGHTの組み合わせを使用する場合を除き、クエリのパフォーマンスを向上させることを示しています。

  2. 3.aで説明されている結論に関して、PolarDBの実験は、TPC-Hのクエリにわずかな量の競合しか存在しないことを示している。 したがって、ローカルハッシュテーブルは実際のシナリオではめったに使用されず、このため、メモ化対応メソッドは、hash JOIN + HASH GROUP BYメソッドと同様のクエリ性能を発揮します。 paper_2の比較では、memoizing対応メソッドの有効性を示すことはできません PolarDBの実験では、直接ロックを実行したときに競合を測定します。

結論

GroupJoinは、ランタイム中の繰り返し作業を排除し、一部のシナリオでクエリのパフォーマンスを向上させます。 この効果は、実際の使用において検証される。 この観点から、GroupJoinは便利です。

ただし、GroupJoinはすべてのクエリシナリオに適しているわけではありません。 GroupJoinは、次の条件が満たされる場合にのみ適用されます。EQUAL JOINとGROUP BYの両方が実行され、グループ化キーが片側の結合キーと同じであり、特定の制限がaggr関数と実装方法に設定されます。 これにより、GroupJoin実行計画の実装と保守が困難になります。 開発者にとっては、すべてのシナリオでSQLクエリの効率を向上させるために広く使用できる方法を好むかもしれません。 この観点から、GroupJoinは期待したほど効果的ではありません。

GroupJoinを使用する場合は、GroupJoinの実行計画を一般化して、一般的なシナリオに適用できるようにすることを推奨します。 このようにして、GroupJoinの使用を最大化することができる。