PolarDB for PostgreSQL (Oracleと互換) では、Elastic Parallel Query機能を使用して分析クエリを実行できるため、一部のハイブリッドトランザクション /分析処理 (HTAP) 機能を使用できます。 このトピックでは、この機能を使用して分析クエリのパフォーマンスを向上させる方法について説明します。
Elastic Parallel Query機能の仕組み
Elastic Parallel Queryでは、クエリは複数のノードで並列に実行されます。 クエリの実行方法を調整するノードは、クエリコーディネータ (QC) ノードと呼ばれ、他のノードは、並列実行 (PX) ノードと呼ばれる。 クエリ要求が開始された後、QCノードはクエリの実行プランをシャードに分割し、シャードをPXノードにルーティングします。 各PXノードは、実行プランの割り当てられた部分を実行し、クエリ結果をQCノードに送信します。 次いで、QCノードは、クエリ結果を集約する。
前の図では、RO1はQCノードであり、RO2、RO3、およびRO4はPXノードです。 RO1がクエリ要求を受信した後、RO1はクエリの実行プランを3つのシャードに分割し、シャードをRO2、RO3、およびRO4にルーティングします。 各PXノードは、実行プランの割り当てられた部分を実行し、共有ストレージシステムPolar File system (PolarFS) から必要なデータブロックを取得し、クエリ結果をQCノードに送信します。 次いで、QCノードは、クエリ結果を組み合わせ、最終結果を返す。
注意事項
各クエリを並列で実行するには、複数の読み取り専用ノードを使用する必要があるため、Elastic parallel queryは、実行頻度の低い分析クエリにのみ適しています。
Elastic Parallel Query機能を使用して、さまざまなレベルで分析クエリを実行する
Elastic Parallel Query機能を使用して、次の3つの粒度レベルで分析クエリを実行できます。
システムレベル: 関連するパラメーターを設定して、すべてのクエリとすべてのセッションでElastic Parallel Query機能を有効にするか無効にするかを指定します。
セッションレベル: ALTER Sessionステートメントを実行するか、セッションレベルのGUCパラメーターを設定して、現在のセッションのElastic Parallel Query機能を有効にするか無効にするかを指定します。
クエリレベル: ヒントを使用して、特定のクエリに対してElastic Parallel Query機能を有効にするか無効にするかを指定します。
パラメーター
デフォルトでは、Elastic Parallel Query機能はPolarDB for PostgreSQL (Compatible with Oracle) で無効になっています。 この機能を使用するには、次の図に示すパラメーターを設定します。
パラメーター | Parameters |
polar_cluster_map | PolarDB for PostgreSQL (Oracleと互換) のすべての読み取り専用ノードの名前を照会します。 このパラメーターは設定できません。 読み取り専用ノードを追加するたびに、パラメーターに返されるノード名のリストが自動的に更新されます。 説明 このパラメーターは、マイナーカーネルバージョン1.1.20 (1月2022日リリース) 以前を使用するクラスターでのみ使用できます。 |
polar_px_nodes | クエリが複数のノードで実行される読み取り専用ノードを指定します。 このパラメーターは既定では空です。これは、すべての読み取り専用ノードが並列実行に使用されることを示します。 並列実行に特定のノードを使用する場合は、使用するノードの名前にパラメーターを設定します。 ノード名はコンマ (,) で区切ります。 例:
|
polar_px_enable_replay_wait | 強い整合性を有効にするかどうかを指定します。 有効な値: onとoff。 PolarDB for PostgreSQL (Oracleと互換) クラスターのプライマリノードと読み取り専用ノードの間に遅延があります。 たとえば、プライマリノードがCREATE TABLEステートメントを実行した後、読み取り専用ノードがプライマリノードと同期されるように、このDDLステートメントが読み取り専用ノードで再生されます。 このリプレイは遅延を引き起こします。 デフォルト値はオフです。これは、強い一貫性が無効になっていることを示します。 パラメーターをoffに設定すると、ログの再生によりプライマリノードと読み取り専用ノードの間に長い遅延が発生し、読み取り専用ノードがDDL操作の最新のログレコードの読み取りに失敗する可能性があります。 指定したデータベースロールに対して、このパラメーターをonに設定することもできます。 |
polar_px_max_workers_number | Elastic Parallel Queryのノードで実行できるワーカープロセスの最大数を指定します。 デフォルト値は 30 です。 このパラメーターは、各ノードの並列処理の程度を制限するために使用されます。 Elastic Parallel Queryのすべてのセッションの各ノードのワーカープロセスの数は、このパラメーターの値を超えることはできません。 |
polar_enable_px | Elastic Parallel Query機能を有効にするかどうかを指定します。 デフォルト値はoffで、この機能が無効になっていることを示します。 |
polar_px_dop_per_node | 現在のセッションでのElastic Parallel Queryの並列処理の度合いを指定します。 デフォルト値は 1 です。 オペレーティングシステムのコア数に値を設定することを推奨します。 polar_px_dop_per_nodeをNに設定すると、各ノードはセッションに対してN pxワーカープロセスを使用してクエリを並行して実行します。 |
px_workers | 指定したテーブルに機能を適用するかどうかを指定します。 デフォルトでは、この機能はテーブルに適用されません。 この機能は、コンピューティングリソースを消費します。 消費されるコンピューティングリソースを削減するために、このパラメーターを設定して、機能が適用されるテーブルを指定できます。 次のコードは、このパラメーターの設定方法を説明する例を示しています。
|
synchronous_commit | データベースがトランザクションをコミットしたときにクライアントに成功メッセージを返す前に、トランザクションがWALログがディスクに書き込まれるのを待つ必要があるかどうかを指定します。 デフォルト値 : on。 有効な値:
説明 パラメータは、PXモードでonに設定されます。 |
例
次のセクションでは、Elastic Parallel Query機能の効果について説明します。 この例では、単一テーブルクエリが実行されます。
背景情報
次のステートメントを実行してtestという名前のテーブルを作成し、テーブルにデータを挿入します。
CREATE TABLE test(id int);
INSERT INTO test SELECT generate_series(1,1000000);
EXPLAIN SELECT * FROM test;
デフォルトでは、Elastic Parallel Query機能は無効になっています。 単一テーブルクエリのネイティブ実行計画では、次のコードに示すように、シーケンシャルスキャン (Seq scan) を実行します。
QUERY PLAN
--------------------------------------------------------
Seq Scan on test (cost=0.00..35.50 rows=2550 width=4)
(1 row)
Elastic Parallel Query機能を有効にするには、次の手順を実行します。
testという名前のテーブルに対してこの機能を有効にします。
ALTER TABLE test SET (px_workers=1); SET polar_enable_px=on; EXPLAIN SELECT * FROM test;
次のクエリ結果が返されます。
QUERY PLAN ------------------------------------------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) (cost=0.00..431.00 rows=1 width=4) -> Seq Scan on test (scan partial) (cost=0.00..431.00 rows=1 width=4) Optimizer: PolarDB PX Optimizer (3 rows)
すべての読み取り専用ノードの名前を照会します。
実行するステートメントは、次のとおりです。
SHOW polar_cluster_map;
次のクエリ結果が返されます。
polar_cluster_map ------------------- node1,node2,node3 (1 row)
この例では、クラスターには、node1、node2、およびnode3の3つの読み取り専用ノードがあります。
Elastic Parallel Queryのnode1とnode2を指定します。
実行するステートメントは、次のとおりです。
SET polar_px_nodes='node1,node2';
Elastic Parallel Queryに指定されたノードを照会します。
SHOW polar_px_nodes ;
次のクエリ結果が返されます。
polar_px_nodes ---------------- node1,node2 (1 row)
パフォーマンスデータ
5つの読み取り専用ノードを使用して並列実行するテストから、次のパフォーマンスデータが得られます。
SELECT COUNT(*)
をフルテーブルスキャンで実行すると、Elastic Parallel Queryはシングルノード並列実行の60倍の速度になります。TPC-Hクエリでは、Elastic Parallel Queryはシングルノード並列実行の30倍高速です。
説明この例では、TPC-Hベンチマークに基づくテストが実装されていますが、TPC-Hベンチマークテストのすべての要件を満たしているわけではありません。 したがって、テスト結果は、TPC-Hのベンチマークテストの公表された結果と比較できない可能性があります。
Elastic Parallel Queryのレベルを指定する
このセクションでは、Elastic Parallel Query機能を使用して、さまざまな粒度レベルで分析クエリを実行する方法について説明します。
システムレベル
システムレベルでElastic Parallel Query機能を使用する場合は、グローバルなGrand Unified Configuration (GUC) パラメーターを設定して、機能を有効にし、並列処理の程度を指定します。
例
postgres=# alter system set polar_enable_px=1; ALTER SYSTEM postgres=# alter system set polar_px_dop_per_node=1; ALTER SYSTEM postgres=# select pg_reload_conf(); pg_reload_conf ---------------- t (1 row) postgres=# \c postgres You are now connected to database "postgres" as user "postgres". postgres=# drop table if exists t1; DROP TABLE postgres=# select id into t1 from generate_series(1, 1000) as id order by id desc; SELECT 1000 postgres=# alter table t1 set (px_workers=1); ALTER TABLE postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
セッションレベル
セッションレベルでElastic Parallel Query機能を使用する場合は、ALTER sessionステートメントを実行するか、セッションレベルのGUCパラメーターを設定します。
ALTER SESSION構文
ALTER SESSION ENABLE PARALLEL QUERY ALTER SESSION DISABLE PARALLEL QUERY ALTER SESSION FORCE PARALLEL QUERY [PARALLEL integer]
説明ALTER SESSION ENABLE PARALLEL QUERY
は、ヒントまたは対応する構文を使用して、現在のセッションのElastic Parallel Queryを有効にできることを指定します。ALTER SESSION DISABLE PARALLEL QUERY
は、ヒントまたは対応する構文が指定されている場合でも、現在のセッションがElastic Parallel Queryをサポートしないことを指定します。ALTER SESSION FORCE PARALLEL QUERY <PARALLEL integer>
は、現在のセッションでElastic Parallel Query機能が強制的に有効になっていることを指定します。 <PARALLEL integer> は、並列度を指定する。 <PARALLEL integer> を指定しない場合、データベースのデフォルト値が並列処理の程度として使用されます。 デフォルト値は、polar_px_dop_per_nodeパラメーターで指定された値です。さまざまな方法を使用して、並列処理の度合いを指定できます。 並列度は、方法に基づいて異なる優先度を有する。 ヒントで指定された並列度の優先度が最も高く、FORCE PARALLEL文で指定された並列度の優先度が中程度で、polar_px_dop_per_nodeパラメーターで指定された並列度の優先度が最も低くなります。
ALTER SESSIONステートメントを実行すると、現在のセッションのElastic Parallel Queryの設定が変更されます。 現在のセッションが再接続されると、デフォルトでセッションに対してElastic Parallel Queryが有効になります。
例
--enable postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = true; SET postgres=# alter session enable parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select /*+ PARALLEL(4)*/ * from t1 where id < 10; INFO: [HINTS] PX PARALLEL(4) accepted. QUERY PLAN ------------------------------------------- PX Coordinator 8:1 (slice1; segments: 8) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
--disable postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = true; SET postgres=# alter session disable parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select /*+ PARALLEL(4)*/ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows)
--force postgres=# set polar_enable_px = false; SET postgres=# set polar_px_enable_hint = false; SET postgres=# alter session force parallel query; ALTER SESSION postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# alter session force parallel query parallel 2; ALTER SESSION postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 4:1 (slice1; segments: 4) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
GUCパラメーターの設定
GUCパラメータは、システムまたはセッションレベルで設定できます。 GUCパラメーターを設定して、現在のセッションのElastic Parallel Query機能を有効にするか無効にするかを指定できます。
例
postgres=# set polar_enable_px = true; SET postgres=# set polar_px_dop_per_node = 1; SET postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows)
クエリレベル
クエリレベルでElastic Parallel Query機能を使用する場合は、SQLヒントを使用して機能を有効にし、並列処理の程度を指定します。 次のヒント構文を使用します。
/*+ PARALLEL(DEFAULT) */ /*+ PARALLEL(integer) */ /*+ NO_PARALLEL(tablename) */
説明PARALLEL(DEFAULT)
は、Elastic Parallel Queryを有効にし、デフォルトの並列度を使用することを指定します。 デフォルトの並列度は、polar_px_dop_per_nodeパラメーターで指定されます。PARALLEL(integer)
は、Elastic Parallel Query機能を有効にし、integerパラメーターで指定した並列処理の度合いを使用することを指定します。NO_PARALLEL(tablename)
は、指定されたテーブルに対してElastic Parallel Queryを無効にすることを指定します。 このテーブルを含むクエリの場合、Elastic Parallel Queryは無効になります。これらのヒントは、Oracleが提供するヒントと互換性があります。 複数のPARALLELヒントが使用されている場合は、次の項目に注意してください。
/* +.A.* /* +.B.* /* +.C.*/ などの複数のヒントブロックが一緒に使用される場合、最初のヒントブロックのみが有効になります。
1つのヒントブロックに複数のPARALLELヒント (/* + parallel (a) parallel(B)*/ など) が存在する場合、これらのヒントに指定された並列度によって実行結果が異なります。 これらのヒントに指定されている並列処理の度合いが同じ場合、いずれかのヒントが有効になります。 それ以外の場合、どのヒントも有効になりません。
PARALLELヒントとNO_PARALLELヒントが同じヒントブロックに存在する場合 (/* + parallel (a) no_parallel(t1)*/ など) 、NO_PARALLELヒントは有効になりません。
Elastic Parallel Queryは、PARALLELおよびNO_PARALLELヒントのみをサポートします。
polar_px_enable_hint GUCパラメーターを設定して、Elastic Parallel Queryを有効または無効にします。 このパラメーターのデフォルト値はfalseです。
例
postgres=# set polar_enable_px = false; SET postgres=# set polar_px_dop_per_node = 1; SET postgres=# set polar_px_enable_hint = true; SET postgres=# explain (verbose, costs off) select * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(DEFAULT) */ * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 2:1 (slice1; segments: 2) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(4) */ * from t1 where id < 10; QUERY PLAN ------------------------------------------- PX Coordinator 8:1 (slice1; segments: 8) Output: id -> Partial Seq Scan on public.t1 Output: id Filter: (t1.id < 10) Optimizer: PolarDB PX Optimizer (6 rows) postgres=# explain (verbose, costs off) select /*+ PARALLEL(0) */ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows) postgres=# explain (verbose, costs off) select /*+ NO_PARALLEL(t1) */ * from t1 where id < 10; QUERY PLAN ------------------------ Seq Scan on public.t1 Output: id Filter: (t1.id < 10) (3 rows)
3つのレベルのElastic Parallel Queryに異なる設定を指定した結果
次の表に、3つのレベルのElastic Parallel Queryに異なる設定を指定した場合にクエリの結果に適用されるルールを示します。
システムレベル
セッションレベル
クエリレベル
結果
polar_enable_px=on
polar_px_dop_per_node=X
enable
ヒントが指定されていません
並列度での並列実行X
polar_enable_px=on
polar_px_dop_per_node=X
enable
PARALLEL(Y)
並列度での並列実行Y
polar_enable_px=on
polar_px_dop_per_node=X
enable
NO_PARALLEL
シリアル実行
polar_enable_px=on
polar_px_dop_per_node=X
disable
ヒントが指定されていません
シリアル実行
polar_enable_px=on
polar_px_dop_per_node=X
disable
PARALLEL(Y)
シリアル実行
polar_enable_px=on
polar_px_dop_per_node=X
disable
NO_PARALLEL
シリアル実行
polar_enable_px=on
polar_px_dop_per_node=X
FORCE PARALLEL Z
ヒントが指定されていません
並列度Zでの並列実行
polar_enable_px=on
polar_px_dop_per_node=X
FORCE PARALLEL Z
PARALLEL(Y)
並列度での並列実行Y
polar_enable_px=on
polar_px_dop_per_node=X
FORCE PARALLEL Z
NO_PARALLEL
シリアル実行
polar_enable_px=off
polar_px_dop_per_node=X
enable
ヒントが指定されていません
シリアル実行
polar_enable_px=off
polar_px_dop_per_node=X
enable
PARALLEL(Y)
並列度での並列実行Y
polar_enable_px=off
polar_px_dop_per_node=X
enable
NO_PARALLEL
シリアル実行
polar_enable_px=off
polar_px_dop_per_node=X
disable
ヒントが指定されていません
シリアル実行
polar_enable_px=off
polar_px_dop_per_node=X
disable
PARALLEL(Y)
シリアル実行
polar_enable_px=off
polar_px_dop_per_node=X
disable
NO_PARALLEL
シリアル実行
polar_enable_px=off
polar_px_dop_per_node=X
FORCE PARALLEL Z
ヒントが指定されていません
並列度Zでの並列実行
polar_enable_px=off
polar_px_dop_per_node=X
FORCE PARALLEL Z
PARALLEL(Y)
並列度での並列実行Y
polar_enable_px=off
polar_px_dop_per_node=X
FORCE PARALLEL Z
NO_PARALLEL
シリアル実行