並列クエリの概要
データ量の急速な増加に伴い、クエリ性能とリソース利用率の最適化はデータベース管理における重要な目標となっています。並列度(DOP、Degree of Parallelism) は並列実行能力を測る鍵となる指標であり、クエリ応答時間とシステムスループットを大幅に向上させることができます。
並列クエリは、複数の処理ユニットでタスクを同時に実行することで、SQLクエリの効率を向上させます。その核心的な考え方は、クエリ計画を最適化した上で、システムの計算リソースとI/O能力を最大限活用し、単一クエリの実行を加速することです。
並列クエリの特性
OLTPとOLAPの違い
異なるタイプのSQLクエリは、並列処理においてそれぞれ異なる特性を示します:
- OLTP(オンライントランザクション処理):通常、多数の短いトランザクションを扱い、1回のクエリで処理するデータ量は少なく、並列度への要求は限定的で、トランザクションの高速な応答能力に依存しています。
- OLAP(オンライン分析処理):大規模なデータ分析タスクを傾向とし、膨大なデータセットを処理するため、並列クエリへの依存度が高く、並列度を通じてクエリのスループットと効率を向上させる必要があります。
クエリの分解と演算子の並列化
並列クエリでは、クエリが複数の 演算子(Operator) に分解され、異なる段階で並列処理が実現されます。これらの段階には以下が含まれます:
- データ読み取り:データを並列スキャンします。
- 計算実行:複数の処理ユニットが同時に計算に参加し、集計やソートなどの複雑な操作を加速します。
- 結果出力:データマージと返却を最適化します。
並列クエリを最適化する戦略
分散クエリ計画の生成
分散実行は並列クエリの重要な構成要素です。OceanBaseデータベースでは、分散クエリ計画の生成がクエリ実行の効率を決定します。システムはデータ分布、演算子の依存関係、リソース使用状況を分析することで、効率的な実行計画を構築できます。
詳細な原理については、分散計画の生成を参照してください。
並列度(DOP)の調整
クエリの複雑さとデータ量に応じて、適切に並列度を調整することがクエリ性能を最適化する鍵です:
- 並列度が低すぎる場合:システムリソースを十分に活用できず、クエリ時間が延長します。
- 並列度が高すぎる場合:リソース競合を引き起こし、システムスループットが低下する可能性があります。
クエリ実行計画を監視し、実行時間とリソース使用状況を分析することで、最適なバランスを達成するために並列度を正確に調整できます。
並列度はどのように調整するか?
クエリを加速し、ビジネス要件を満たすために、通常は並列実行によってクエリ時間を最適化します。では、並列リソースはどの程度が適切でしょうか?オプティマイザーでは、並列リソース量は並列度(DOP:Degree of Parallelism)で表現できます。実際のビジネスシナリオでは、並列を有効にするかどうか、並列度の大きさは、クエリの実行状況とビジネス要件に基づいて経験則によって決定されます。
OceanBaseデータベースは、並列度を設定するための手動と自動の2つの方法を提供しています。
オプティマイザーの並列度を手動で選択する
並列度を手動で設定できます。詳細については、パラレル実行の並列度の設定を参照してください。
オプティマイザーの並列度を自動で選択する
Auto DOP
人が並列度を指定する場合、システム変数を使用して、現在のセッション内のすべての実行クエリの並列処理を有効にし、並列度を指定できます。しかし、これは、並列高速化や高いDOPを必要としないクエリに対しても余分な並列実行オーバーヘッドをもたらし、パフォーマンスを低下させる可能性があります。一方、ヒントを使用して特定のクエリの並列度を指定することも可能ですが、これには各業務クエリについて個別に検討する必要があり、業務クエリが多数存在する場合には実行不可能です。
手動で並列度を指定する手間と制限を解決するため、クエリオプティマイザーはAuto DOP機能を利用して、クエリ計画の生成時にクエリの実行時間を評価し、並列処理を有効にするかどうか、および適切な並列度を自動的に判断します。これにより、手動で並列度を指定することによるパフォーマンスの低下を回避できます。
注意
- Auto DOPを有効にした後は、
parallel_min_scan_time_thresholdとparallel_degree_limitの2つの関連パラメータの設定に注意する必要があります。そうでない場合、Auto DOPがAPシステムに悪影響を及ぼす可能性があります。
- Auto DOPは、評価されたクエリの実行コストに基づいて、RTを短縮することを目的に並列処理の有効化とDOPの計算を決定します。業務負荷にユーザーが重視しない低速クエリが含まれる場合は、リソース分離の手法を用いて対処する必要があります。そうでない場合、Auto DOPを有効にした後、すべてのクエリに対してAuto DOPが設定する並列度を使用すると、システムに悪影響を及ぼします。
Auto DOPを有効にする
オプティマイザーのDOP選択戦略は、現在AUTOモードとMANUALモードに分かれています。AUTOモードでは、オプティマイザーがクエリの実際の状況に応じて、自動的に並列処理を有効にし、並列度を決定できます。MANUALモードでは、人為的な介入によってのみ並列処理を有効にできます。
オプティマイザーのDOP選択戦略には2つの制御方法があります。システム変数parallel_degree_policyを使用してグローバルまたはセッションレベルのDOP選択戦略を設定することも、より高い優先順位を持つヒントを使用してクエリレベルのDOP選択戦略を設定することもできます。
注意
パラメータタイプはシステム変数です。グローバルレベルで変数を変更した後、新規接続でのみ変更が有効になります。既存の接続は切断する必要があります。
-- グローバルレベルでAuto DOPを有効にする
set global parallel_degree_policy = AUTO;
-- セッションレベルでAuto DOPを有効にする
set session parallel_degree_policy = AUTO;
set parallel_degree_policy = AUTO;
-- グローバルレベルでAuto DOPを無効にする
set global parallel_degree_policy = MANUAL;
-- セッションレベルでAuto DOPを無効にする
set session parallel_degree_policy = MANUAL;
set parallel_degree_policy = MANUAL;
ヒントはシステム変数よりも優先順位が高く、クエリレベルでAuto DOPの有効/無効を制御できます。
-- ヒントを使用してクエリレベルでAuto DOPを有効にする
select /*+parallel(auto)*/ * from t1;
-- ヒントを使用してクエリレベルでAuto DOPを無効にする
select /*+parallel(manual)*/ * from t1;
select /*+parallel(8)*/ * from t1;
関連パラメータの設定
Auto DOPがクエリのDOPを計算する際、最終的に割り当てるDOPサイズは以下の2つのシステム変数の影響を受けます。異なるデプロイメントリソースとビジネス負荷の条件下では、これら2つのパラメータを調整することでAuto DOPの動作に介入することも可能です。
注意
パラメータタイプはシステム変数です。グローバルレベルで変数を変更した後、新規接続からのみ変更が有効になり、既存の接続は切断する必要があります。
parallel_min_scan_time_threshold:ベーステーブルのスキャンで並列処理を有効にするしきい値を設定します。クエリで並列処理を有効にするかどうか、および使用するDOPのサイズに影響します。パラメータの単位はmsで、デフォルト値は1000、最小値は10です。
適用シナリオ:
パラメータの値を調整することで、APシステム内で並列クエリを有効にする数と使用する並列度を制御します。Auto DOPを有効にした後、注目すべき一部のクエリで並列処理が有効になっていない場合、または使用する並列度が低く並列度の上限に達していない場合は、parallel_min_scan_time_thresholdの設定値を小さくすることができます。調整後、より多くのクエリで並列処理が有効になり、既に並列処理が有効なクエリでもより大きな並列度を使用する可能性があります。逆の場合は、パラメータの設定値を大きくすることができます。
Auto DOPを有効にした後、大量のクエリが高い並列度で並列処理を有効にし、システムのリソースを過度に消費するのを避けるため、パラメータのデフォルト値は比較的保守的です。Auto DOPを有効にする際は、一般的にシステム負荷状況を評価し、パラメータを適切な値まで小さく調整する必要があります。
例:
-- 現在のセッションにおけるベーステーブルスキャンで並列処理を有効にする評価コストのしきい値を10msに設定する
set parallel_min_scan_time_threshold = 10;
-- グローバルにベーステーブルスキャンで並列処理を有効にする評価コストのしきい値を10msに設定する
set global parallel_min_scan_time_threshold = 10;
explain select /*+parallel(auto)*/ * from t1;
-- パラメータを20に設定し、最終的なDOPは4とします。並列処理を有効にした後のベーステーブルスキャンの評価コストは12ミリ秒です
set parallel_min_scan_time_threshold = 20;
=========================================================
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
---------------------------------------------------------
|0 |PX COORDINATOR | |512000 |619089 |
|1 |└─EXCHANGE OUT DISTR |:EX10000|512000 |230501 |
|2 | └─PX BLOCK ITERATOR| |512000 |12189 |
|3 | └─TABLE FULL SCAN|t1 |512000 |12189 |
=========================================================
Outputs & filters:
-------------------------------------
0 - output([INTERNAL_FUNCTION(t1.c1, t1.c2, t1.c3, t1.c4)]), filter(nil), rowset=256
1 - output([INTERNAL_FUNCTION(t1.c1, t1.c2, t1.c3, t1.c4)]), filter(nil), rowset=256
dop=4
-- パラメータを10に設定し、最終的なDOPは6とします。並列処理を有効にした後のベーステーブルスキャンの評価コストは8msです
set parallel_min_scan_time_threshold = 10;
=========================================================
|ID|OPERATOR |NAME |EST.ROWS|EST.TIME(us)|
---------------------------------------------------------
|0 |PX COORDINATOR | |512000 |542256 |
|1 |└─EXCHANGE OUT DISTR |:EX10000|512000 |153667 |
|2 | └─PX BLOCK ITERATOR| |512000 |8126 |
|3 | └─TABLE FULL SCAN|t1 |512000 |8126 |
=========================================================
Outputs & filters:
-------------------------------------
0 - output([INTERNAL_FUNCTION(t1.c1, t1.c2, t1.c3, t1.c4)]), filter(nil), rowset=256
1 - output([INTERNAL_FUNCTION(t1.c1, t1.c2, t1.c3, t1.c4)]), filter(nil), rowset=256
dop=6
parallel_degree_limit:Auto DOPを使用した後に使用できる最大DOPを制限するために使用されます。デフォルト値は0で、この場合オプティマイザーはテナントのCPUとシステム変数parallel_servers_targetに基づいて最大DOPを制限します。
適用シナリオ:
APシステムでAuto DOPを有効にした後、大量のクエリが高い並列度を必要とし、システム負荷が高くなる場合があります。このような場合、parallel_degree_limitを設定することで許可される最大DOPをさらに制限できます。このとき、必要に応じてparallel_degree_limitをCPU数より小さい値に設定します。
システム内で単一のAPクエリのみが実行されている場合、parallel_degree_limitはデフォルト値となり、クエリはCPU数に相当する並列度を最大限に使用できます。Auto DOP下でより高い並列度を必要とする場合は、parallel_degree_limitをCPU数より大きい値に設定することで、CPU数によるDOPの制限を解除できます。この調整は、単一のAPクエリの極限性能最適化時にのみ使用し、本番環境での使用は禁止されています。
例:
-- 現在のセッションでAuto DOPによって指定される最大並列度を8に設定します
set parallel_degree_limit = 8;
-- グローバルでAuto DOPによって指定される最大並列度を8に設定します
set global parallel_degree_limit = 8;
Auto DOPの詳細については、Auto DOPを参照してください。
並列実行
並列実行(Parallel Execution)とは、大規模なタスクを複数の小さなタスクに分割し、複数のスレッドやプロセスを起動してこれらの小タスクを並行的に処理することです。これにより、より多くのCPUおよびI/Oリソースを活用して、操作の応答時間を短縮できます。
並列実行は、並列クエリ(Parallel Query)、並列DDL(Parallel DDL)、並列DML(Parallel DML)に分類されます。
並列実行を開始する方法は以下の2つです:
- 手動で並列度(DOP)またはAuto DOPを指定して並列実行を開始する方法。
- クエリのパーティション数が1より多いパーティションテーブルでは、自動的に並列クエリが開始される方法。
詳細については、並列クエリの実行を参照してください。