パラレルクエリの概要
データ量が急速に増加する中、クエリ性能とリソース利用率の最適化はデータベース管理における重要な目標となっています。並列度(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の設定値を調整する必要があります。設定を怠ると、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で、並列処理を有効にした後のベーステーブルスキャンの評価コストは12msになります。
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より大きいパーティションテーブルでは、自動的にパラレルクエリが開始されます。
詳細については、パラレルクエリの実行を参照してください。