PolarDB-X's in constant query

シナリオ

実際のシナリオでは、定数インジケータに基づいて IN クエリを実行する必要が多く、IN 値はパーティションキーであることがよくあります。たとえば、E コマースのシナリオでは、購入者テーブルとオーダーテーブルの 2 つのテーブルがあります。オーダーの詳細情報はオーダーテーブルに記録され、オーダー ID に基づいてハッシュ分割されます。購入者テーブルには、購入者 ID とそれに関連付けられたオーダー ID が保存されます。購入者は自身が購入したすべてのオーダーをクエリすることがよくあります。一般的な方法は、まず購入者テーブルをクエリして購入者のすべてのオーダー ID を取得し、次にそのオーダー ID に基づいてオーダーの詳細情報をクエリします。オーダーテーブルに 4 つのパーティションがあり、購入者 A のオーダー ID が 1、2、4、5、9 であると仮定すると、次の SQL が生成されます。つまり、5 つの値を持つ IN 条件クエリです。

論理 SQL: select * from order where order_id in (1, 2, 4, 5, 9);

実行モード

MySQL とは異なり、PolarDB-X アーキテクチャは計算レイヤーとストレージレイヤーに分割できます。ストレージレイヤーの DN ノード (データノード) にすべてのデータが格納されます。詳細な背景情報については、PolarDB-X の紹介コラムを参照してください。

この論理 SQL を受け取った後、計算ノードはどのようにして DN ノードからデータを取得し、計算を実行するのでしょうか。

Naive 実行モード

すべての IN 値を含む物理 SQL がすべてのパーティションに配布されます。このナイーブな実装方法には 2 つの問題があります。第一に、オーダーテーブルのシャード数が増加するにつれて、スキャン対象のシャード数が急激に増加するのに対し、購入者のオーダーデータが存在するシャード数は増加しません。第二に、IN 値の数が増加するにつれて、発行される物理 SQL の実行がインデックススキャンからフルテーブルスキャンに切り替わります。これら 2 つの理由により、RT が急激に上昇します。

動的クリッピングベースの実装

上記の議論から、必要なデータを含まないパーティションを除外できることを期待します。IN フィールドがパーティションキーであるため、パーティションアルゴリズムを使用して各 IN 値のパーティションを計算できます。

hash(1) = 1, hash(2) = 2, hash(4) = 4, hash(5) = 1, hash(9) = 1

上記の例を取ると、パーティション 3 に物理 SQL を発行する必要がないことは明らかです。さらに、シャード 1 にはオーダー ID 1、5、9 のデータのみが含まれ、オーダー ID 2 や 4 のデータは含まれないため、物理 SQL に含まれる IN 値をさらに絞り込めます。

発行する SQL が 3 つのパーティションに関与することが分かった場合、3 つの物理 SQL をどのように発行するか、つまり SQL の発行と結果の待機の並列度はどうなるでしょうか。明らかに 2 つの極端な方法があります。1 つはすべて直列で、非常に非効率的です。もう 1 つはすべて並列で、複数のスレッドで同時に各パーティションにすべての物理 SQL を送信できます。この方法の問題点は、パーティション数が多すぎる場合、システムに大きな負荷がかかり、大量のスレッドコンテキストスイッチが発生することです。以上の理由から、物理 SQL の並列度はデフォルトでマシンの CPU コア数に設定し、スライドウィンドウ方式で物理 SQL を発行します。

さらに、各パーティションに配布される物理 SQL に IN 値が多すぎないことを期待します。そうでない場合、DN ノードでの実行時にインデックススキャンではなくフルテーブルスキャンが実行される可能性が高くなります。そのため、IN 値が多い場合、IN 値を分割してバッチで配布します。実行プロセスは次の図の通りです。

上記の例を例に取ると、CN ノードが 2 コアのみで、毎回発行する物理 SQL の IN 値が 2 つを超えないと仮定すると (実際にはそれほど小さく設定しませんが)、合計 4 つの物理 SQL を発行し、2 バッチに分割されます。つまり、計算ノードとデータノード間で 2 回のネットワークインタラクションが必要です。物理 SQL を 2 つだけ発行する場合、1 バッチですべての物理 SQL を発行でき、計算ノードとデータノード間のネットワークインタラクションは 1 回で済みます。したがって、RT に対する要件が厳しいユーザーには、IN 値の数を少なくして、関与するパーティション数が CPU コア数を超えず、各パーティションで 1 つの物理 SQL のみ発行されるようにすることを推奨します。

IN 値数の不定性による課題

SQL 実行を高速化するため、パラメータ化 SQL の実行計画をキャッシュします。ビジネスコード内の IN 値の数は異なる場合があり、これが原因で実行計画のキャッシュスペースが異なる IN 値数の SQL で埋め尽くされ、他の SQL の実行計画の無効化を招く可能性があります。この問題の解決策は単純です。IN リストを疑問符に置き換えることで、上記の状況を回避します。

テスト

2 × 16C64G ノード構成のテスト環境において、64 個のサブテーブルからなり合計数百万件のレコードを含むテーブルに対し、異なる IN 値数と同時実行数でテストを実施しました。パーティショニング方式はハッシュパーティショニングです。テスト結果は以下の通りです。

Related Articles

Explore More Special Offers

  1. Short Message Service(SMS) & Mail Service

    50,000 email package starts as low as USD 1.99, 120 short messages start at only USD 1.00

phone お問い合わせ
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.