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

PolarDB:クエリのin句の値の数を決定する

最終更新日:May 27, 2024

このトピックでは、PolarDB-X 1.0でクエリを実行するときに、in句の最適な値の数を決定する方法について説明します。

特徴

実際のシナリオでは、多くの場合、Inクエリを実行するためのクエリ条件として定数メトリックを使用する必要があります。 INクエリごとに、in句のフィールド値はパーティションキーの値です。 たとえば、電子商取引のシナリオでは、すべての注文がOrderという名前のテーブルに記録されます。 このテーブルは、オーダーIDによって分割される。 買い手は、注文リストに基づいて特定の注文に関する詳細を問い合わせることが多い。 購入者に2つの注文がある場合、クエリのin句の値の数は2です。 理論的には、クエリは2つのシャードにルーティングされます。 次のサンプルコードは、SQL文の例を示しています。

SELECT * FROM ORDER HERE ORDER_ID IN (id1,id2)

注文数が増えると、in句の値の数が増えます。 この場合、Inクエリは、すべてのシャードにルーティングされる必要があり得る。 これにより、クエリの応答時間が増加します。 in句の値の数と応答時間の関係、およびスキャンするシャードの数と応答時間の関係を次の図に示します。

25337301

スキャンのワークロードを最小限に抑え、in句内の値の数の増加によって引き起こされるSQL文の数を減らすために、PolarDB-X 1.0は、IN句内の値の数に基づいて実行される動的パーティションプルーニングをV5.4.8-16069335サポートします。

前の例のOrderテーブルに128のシャードがあり、in句の値の数が128の場合は、次のクエリを実行する必要があります。

SELECT * FROM ORDER HERE ORDER_ID IN (id1,id2,id3... id128)

PolarDB-X 1.0 V5.4.8-16069335より前のバージョンでは、各値が別のシャードにある場合、Inクエリは最大128のシャードにルーティングできます。 ApsaraDB RDS for MySQLに送信される各物理クエリステートメントのIN句には、値がプルーニングされていないため、128値が含まれています。 これにより、SQL文を実行する作業負荷が増加します。 次のサンプルコードは、SQL文の例を示しています。

SELECT * FROM ORDER HERE ORDER_ID_1 IN (id1,id2,id3... id128);
SELECT * FROM ORDER ORDER_ID_2 IN (id1,id2,id3... id128);
SELECT * FROM ORDER HERE ORDER_ID_3 IN (id1,id2,id3... id128);
.....
SELECT * FROM ORDER HERE ORDER_ID_128 IN (id1,id2,id3... id128); 

PolarDB-X 1.0 V5.4.8-16069335では、PolarDB-X 1.0は、Inクエリがコンピューティングレイヤーでルーティングされるシャードを計算します。 各物理クエリステートメントがApsaraDB RDS for MySQLに送信される前に、PolarDB-X 1.0は動的パーティションプルーニング機能を使用して、クエリのSQLステートメントのIN句にシャードに格納されている値のみが含まれるようにします。 これにより、INクエリのスループットが向上し、応答時間が短縮されます。 次のサンプルコードは、SQL文の例を示しています。

SELECT * からORDER_ID_1 IN (id1);
SELECT * からORDER_ID_2 IN (id2,id12);
SELECT * FROM ORDER HERE ORDER_ID_3 IN (id3,id4,id5);
.....
SELECT * FROM ORDER HERE ORDER_ID_32 IN (id100....id128); 

さらに、PolarDB-X 1.0では、単一ノードの並列実行機能を使用して、異なるシャードでInクエリを並列に実行します。 たとえば、クエリのin句の値が32のシャードに分散されている場合、各クエリの並列処理度の値は、ノードのコア数に等しくなります。 PolarDB-X 1.0インスタンスのノードに16個のコアがある場合、並列処理度のデフォルト値は16です。 この場合、32シャードにルーティングされたInクエリは2つのバッチで完了します。

次のルールに基づいて、クエリのin句の値の数を決定することを推奨します。
  • シャードの数よりも大幅に小さい数値を指定します。 このように、クエリが実行されるたびにすべてのシャードをスキャンする必要はありません。
  • 値の数がビジネス開発のために増加しないようにしてください。 これにより、ビジネス開発のためにクエリのパフォーマンスが低下するのを防ぎます。
  • 応答時間が低く、スループットが高いことを確認するには、8〜32の範囲の数値を指定します。

上記の推奨事項に従うと、ビジネスで線形スケーラビリティを実行して、応答時間の明らかな変動なしに同時INクエリを処理できます。 たとえば、16コアノードがデプロイされているPolarDB-X 1.0インスタンスは、10,000のinクエリを同時に実行できます。 別の16コアノードが追加されると、PolarDB-X 1.0インスタンスは20,000のINクエリを同時に実行できます。

25337302

比較テスト

このテストは、低応答時間と高スループットを確保するために、クエリのin句で最適な値の数を決定するのに役立ちます。 テスト環境では、2つのノードと64のシャードを持つテーブルが使用されます。 各ノードの仕様は、16コア、64 GBメモリです。 各テーブルシャードには、数百万のデータレコードが含まれます。 テスト結果は、in句の値の数と同時クエリの数が増加したときの応答時間とスループットの変化を示しています。 PolarDB-X 1.0 V5.4.8-16069335以降では、動的パーティションプルーニング機能がInクエリを処理するように最適化されています。 クエリの各SQL文のin句の過剰な値はプルーニングされます。 次の図はテスト結果を示しています。

  1. 次の図は、動的パーティションプルーニング機能が有効になった後、同時クエリの数とin句の値の数が増加したときの応答時間の変化を示しています。 25337303
  2. 次の図は、動的パーティションプルーニング機能が有効になった後、同時クエリの数とin句の値の数が増加したときのスループットの変化を示しています。 25337304
  3. 次の図は、動的パーティションプルーニング機能が無効になった後、同時クエリの数とin句の値の数が増加したときの応答時間の変化を示しています。 25337305
  4. 次の図は、動的パーティションプルーニング機能が無効になった後、同時クエリの数とin句の値の数が増加したときのスループットの変化を示しています。 25337306
この比較テストから次の結論を引き出すことができます。
  • in句の値の数が8〜32の場合、低応答時間と高スループットを維持できます。 この場合、並列度の値は、PolarDB-X 1.0が提供する単一ノード並列実行機能の並列度のデフォルト値に近い値になります。 並列度のデフォルト値は、ノードのコア数に等しい。
  • 動的パーティションプルーニング機能を有効にするには、PolarDB-X 1.0をV5.4.8以降に更新することを推奨します。 PolarDB-X 1.0 V5.4.8-16069335によって提供される動的パーティションプルーニング機能を有効にすると、INクエリの応答時間が短縮され、INクエリのスループットが向上します。