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

PolarDB:ePQヒントインジェクション

最終更新日:Jun 05, 2024

このトピックでは、ePQヒントインジェクション機能とその使用方法について説明します。

前提条件

ePQヒントインジェクションは、pg_hint_planプラグインに依存します。 shared_preload_librariesパラメーターの値にpg_hint_planを追加する必要があります。 詳細は、「クラスターパラメーターの設定」をご参照ください。

概要

ePQヒントインジェクション機能は、マルチノードElastic Parallel Query (ePQ) で使用されます。 データベースの運用中に、並列実行 (PX) ヒントをSQLに直接追加できない場合は、ePQヒントインジェクション機能を使用してPXヒントを追加できます。 SQLを変更する必要なしに、SQL実行ePQヒントインジェクションを許可するかどうかを設定できます。

使用法

プラグインを作成して機能を有効にする

説明

データベースまたはロールに基づいて機能を有効にすることを推奨します。 この例では、postgresという名前のデータベースに対して機能が有効になっています。

拡張子polar_sql_mappingを作成
ます。拡張子pg_hint_planを作成します。alter database postgres set pg_hint_plan.enable_hint TO on; 

ePQヒントインジェクション機能の使用

次のサンプルSQLステートメントでは、ePQヒントインジェクション機能について説明します。

t1から選択カウント (*) を説明します。カウント (*) をt1から選択します。

データの準備

作成テーブルt1(c1 int,c2 int);
t1 select generate_series(1,1000) 、generate_series(1,1000) に挿入します。-- px_workersパラメーターを設定して、t1テーブルの並列実行を有効にします。
変更テーブルt1セット (px_workers=1000); 

マッピングテーブルへのSQL文の書き込み

-- プラグインを作成する
拡張子polar_sql_mappingを作成します。拡張子pg_hint_planを作成します。alter database postgres set pg_hint_plan.enable_hint TO on;
-- SQL文をpxマッピングテーブルに書き込む
select polar_sql_mapping.insert_px_mapping (t1からのselect count(*) を説明する; ');
select polar_sql_mapping.insert_px_mapping (t1;'からカウント (*) を選択);
-- SQL文をnonpxマッピングテーブルに書き込む
select polar_sql_mapping.insert_nonpx_mapping (t1からのselect count(*) を説明する; ');
select polar_sql_mapping.insert_nonpx_mapping (t1;'からカウント (*) を選択); 
説明

説明:

  • polar_sql_mapping.insert_px_mapping: SQL文をpolar_sql_mapping.polar_px_mapping_tableに書き換えます。 このテーブルは、PX機能が無効の場合に使用されます。 目的は、polar_px_mapping_tableテーブルで一致するSQL文に /* + PX()*/ を追加することです。 たとえば、select count(*) from t1; ステートメントは、/* + PX()*/ select count(*) from t1; に書き換えられます。 このように、ePQ機能が無効になっている場合でも、指定された長いクエリに対してePQを実行できます。

  • polar_sql_mapping.insert_nonpx_mapping: SQL文をpolar_sql_mapping.polar_nonpx_mapping_tableに書き換えます。 このテーブルは、PX機能が有効な場合に使用されます。 目的は、polar_nonpx_mapping_tableテーブルで一致するSQL文に /* + NoPX()*/ を追加することです。 たとえば、select count(*) from t1ステートメントは、/* + NoPX()*/ select count(*) from t1; に書き換えられます。 このように、機能が有効になっているときに、ePQ機能を使用せずに短いクエリを実行できます。

書き換え機能の有効化

データベースに基づいてパラメーターを設定することを推奨します。 この例では、現在のデータベースの名前はpostgresです。

-- 書き換え機能を有効にする
-- alter database postgresステートメントは、新しいセッションに対してのみ有効です。 設定を有効にするには、接続を再起動する必要があります。 postgresは、現在のデータベースの名前に置き換えることができます。
alter database postgres set polar_sql_mapping.use_px_sql_mapping=true;

-通知を有効にしてメッセージを表示する
pg_hint_plan.debug_printをオンに設定します。通知にpg_hint_plan.message_levelを設定します。SET polar_sql_mapping.log_usage=通知;
SET client_min_messagesに通知します。-- 書き換え結果を確認します。
説明する選択カウント (*) からt1; 

次の出力は、書き換えが成功したことを示します。

postgres=# t1からの選択カウント (*) を説明します。注意: sqlマッピングが存在します。 id = 1
NOTICE: px sql mapping: sqlを '/* + PX()*/explain select count(*) from t1;' に変更します。
注意: pg_hint_plan:
使用されるヒント:
PX()
使用されないヒント:
重複ヒント:
エラーヒント:

                                     クエリ計画
-------------------------------------------------------------------------------------
 集計の完了 (コスト=0.00 .. 431.00行=1幅=8)
   -> PXコーディネーター6:1 (slice1; セグメント: 6) (コスト=0.00 .. 431.00行=1幅=8)
         -> 部分集約 (コスト=0.00 .. 431.00行=1幅=8)
               -> t1の部分Seqスキャン (コスト=0.00 .. 431.00行=167幅=1)
 Optimizer: PolarDB PX Optimizer
(5行)

postgres=# 選択カウント (*) からt1;
注意: sqlマッピングが存在します。 id = 2
注意: px sql mapping: sqlを「 /* + PX()*/select count(*) from t1; 」に変更します。
注意: pg_hint_plan:
使用されるヒント:
PX()
使用されないヒント:
重複ヒント:
エラーヒント:

 カウント
-------
  1000
(1行) 

polar_enable_pxがonに設定されている場合、クエリはPX機能を使用しないクエリに書き換えられます。

polar_enable_px=1を設定します。説明する選択カウント (*) からt1; 

サンプル結果:

postgres=# set polar_enable_px=1;
セット
postgres=# 選択カウント (*) からt1;
注意: sqlマッピングが存在します。 id = 2
NOTICE: px sql mapping: sqlを「 /* + NoPX()*/select count(*) from t1; 」に変更します。
注意: pg_hint_plan:
使用されるヒント:
NoPX (0)
使用されないヒント:
重複ヒント:
エラーヒント:

 カウント
-------
  1000
(1行)

postgres=# t1から選択カウント (*) を説明します。注意: sqlマッピングが存在します。 id = 1
NOTICE: px sql mapping: sqlを '/* + NoPX()*/explain select count(*) from t1;' に変更します。
注意: pg_hint_plan:
使用されるヒント:
NoPX (0)
使用されないヒント:
重複ヒント:
エラーヒント:

                         クエリ計画
------------------------------------------------------------
 集計 (コスト=17.50 .. 17.51行=1幅=8)
   -> Seqスキャンでt1 (コスト=0.00 .. 15.00行=1000幅=0)
(2行) 

parse_treeマッチングの有効化

デフォルトでは、ePQ Hint Injectionは文字列マッチングを使用します。 スペースと改行は正確に一致する必要があります。 ePQヒントインジェクションには、スペースと改行を無視するparse_treeマッチングモードもあります。 ただし、parse_treeモードでは、マッチング時間が文字列マッチングの2倍に増加します。. このモードを有効にするには、polar_sql_mapping.use_px_parse_matchパラメーターをtrueに設定します。

-スペースのためにマッチングが失敗しました。
t1から選択カウント (*) を説明します。-- parse_treeマッチングを有効にする
alter database postgres set polar_sql_mapping.use_px_parse_match =true;
-セッションを再起動する
-マッチングが成功したかどうかを確認する
説明する選択カウント (*) からt1; 

サンプル結果:

postgres=# t1からの選択カウント (*) を説明します。
                         クエリ計画
------------------------------------------------------------
 集計 (コスト=17.50 .. 17.51行=1幅=8)
   -> Seqスキャンでt1 (コスト=0.00 .. 15.00行=1000幅=0)
(2行)

postgres=# alter database postgres set polar_sql_mapping.use_px_parse_match=true;
ALTERデータベース

postgres=# t1からの選択カウント (*) を説明します。注意: Parse tree match hit。 Sqlマッピングが存在します。 id = 1
NOTICE: px sql mapping: sqlを '/* + PX()*/explain select count(*) from t1;' に変更します。
注意: pg_hint_plan:
使用されるヒント:
PX()
使用されないヒント:
重複ヒント:
エラーヒント:

                                     クエリ計画
-------------------------------------------------------------------------------------
 集計の完了 (コスト=0.00 .. 431.00行=1幅=8)
   -> PXコーディネーター6:1 (slice1; セグメント: 6) (コスト=0.00 .. 431.00行=1幅=8)
         -> 部分集約 (コスト=0.00 .. 431.00行=1幅=8)
               -> t1の部分Seqスキャン (コスト=0.00 .. 431.00行=167幅=1)
 Optimizer: PolarDB PX Optimizer
(5行) 
説明

照合用SQLとselect polar_sql_mapping.insert_px_mapping() テーブルに挿入するSQLは、次の条件を満たしている必要があります。

  • SELECTまたはEXPLAINコマンドを含むDQLステートメント。

  • /* + PX()*/ または /* + NoPX()*/ を含まないでください。

  • 構文は有効です。

3つの条件を満たさないSQL文はエラーをトリガーします。

一致失敗

一致が失敗した場合は、次のパラメーターを変更してログを確認できます。

-- 通知を有効にしてメッセージを表示する
pg_hint_plan.debug_printをオンに設定します。通知にpg_hint_plan.message_levelを設定します。SET polar_sql_mapping.log_usage=通知;
SET client_min_messagesに通知します。

拡張プロトコルのSQLとPreparedStmt

ほとんどのアプリケーションはPreparedStmtを使用します。 新しいSQLステートメントを作成するときは、? の代わりにプレースホルダ $nを使用します。 例: image..png

引用符 (') を含むSQLステートメント

SQL文に引用符 (') が含まれている場合は、照合用に別の引用符のペア (') を追加する必要があります。

例:

select instr(varchar_test,'arh') from test_datatype_listここで、varchar_testはnullではありません。

ステートメントは次のように変更する必要があります。

select polar_sql_mapping.insert_px_mapping('select instr(varchar_test、''arh'') from test_datatype_list (varchar_testはnull順序ではない);

マッピングに関与するSQL文の表示

-- ePQ機能がクエリに使用されるマッピングテーブルの内容を表示する
postgres=# select * from polar_sql_mapping.polar_px_mapping_table;
 id | source_sql | target_sql

---- + ------------------------------------------------ + ---------------------------------
------------------------
  1 | select * from polar_sql_mapping.px_query_info; | /* + PX()*/select * from polar_sql
_mapping.px_query_info;
  2 | 選択カウント (*) からt1; | /* + PX()*/select count(*) from t1
;
(2行)

-ePQ機能がクエリに使用されるマッピングテーブルのコンテンツを表示します
postgres=# select * from polar_sql_mapping.polar_nonpx_mapping_table;
 id | source_sql | target_sql
---- ----------- -----------------
(0行)

スローSQL収集機能

低速SQL収集機能は、しきい値以上またはしきい値以下の期間で最新のN個のSQL(Nはpx_max_numパラメーターによって決定されます) をハッシュテーブルに収集します。 select polar_sql_mapping.insert_px_mapping_id(id); を実行すると、SQL文全体を入力しなくても、収集したSQLをマッピングテーブルに追加できます。 パラメーター:

パラメーター

説明

polar_sql_mapping.px_record_query

収集機能を有効にするかどうかを指定します。 有効な値:

  • true

  • false (デフォルト)

polar_sql_mapping.px_record_upper_or_lower

SQL文をしきい値以上またはしきい値以下の期間で収集するかどうかを指定します。 有効な値:

  • true (デフォルト): しきい値以上の期間でSQL文を収集します。

  • false: しきい値以下の期間でSQL文を収集します。

polar_sql_mapping.px_record_duration_time

期間のしきい値。 デフォルト値: 10000 単位:ミリ秒。

polar_sql_mapping.px_max_num

収集できるSQL文の最大数。 デフォルト値は 20 です。

説明

このパラメーターを変更した後、データベースを再起動する必要があります。

polar_sql_mapping.px_record_explain

EXPLAINステートメントを収集するかどうかを指定します。

  • true

  • false (デフォルト)

polar_sql_mapping.px_evict_entry_num

一度に削除されるエントリの数。 既定値:5

収集テーブルの照会

px_psm_query_info_internal() はプラグインの組み込み関数で、完全なハッシュテーブルをクエリするために使用できます。

select * from polar_sql_mapping.px_query_info;

コレクションテーブルのクリア

次のステートメントを使用して、コレクションテーブルをクリアできます。

select polar_sql_mapping.px_query_info_clear();

例:

-- データベースに基づいてパラメーターを設定します。
alter database postgres set polar_sql_mapping.px_record_query=1;
alter database postgres set polar_sql_mapping.px_record_upper_or_lower=1;
-- 3秒以上のSQL文が収集されます。
alter database postgres set polar_sql_mapping.px_record_duration_time=3000;

-- 3秒以上の期間でSQL文を実行します。
t1からsum(c1) を選択します。c1=(select count(pg_sleep(3))); 

polar_sql_mapping.px_query_infoテーブルを照会します。 次の結果は、クエリが成功したことを示します。

select * from polar_sql_mapping.px_query_info;
 id | query | execution_time | 呼び出し
---- -------------------------------------------------------------- ---------------- ------
  1 | t1からsum(c1) を選択します。c1=(select count(pg_sleep(3))); | 3004 | 1
(1行) 

マッピングテーブルへのSQL文の追加

-- polar_px_mapping_tableにSQL文を追加する
select polar_sql_mapping.insert_px_mapping_id(1);
-- polar_nonpx_mapping_tableにSQL文を追加する
select polar_sql_mapping.insert_nonpx_mapping_id(1); 

すべてのSQL文をマッピングテーブルに追加する

-- すべてのクエリをpolar_px_mapping_tableに追加する
polar_sql_mapping.px_query_infoからpolar_sql_mapping.insert_px_mapping_id(id) を選択します。-- polar_nonpx_mapping_tableにすべてのクエリを追加します。
selectからpolar_sql_mapping.insert_nonpx_mapping_id(id) を選択します。

書き換え

サンプル結果:

postgres=# select sum(c1) from t1ここで、c1=(select count(pg_sleep(3)));
注意: Parse tree match hit。 Sqlマッピングが存在します。 id = 6
NOTICE: px sql mapping: sqlをt1から '/* + PX()*/select sum(c1) に変更します。ここで、c1=(select count(pg_sleep(3)));' 。
注意: pg_hint_plan:
使用されるヒント:
PX()
使用されないヒント:
重複ヒント:
エラーヒント:

 合計
-----
   1
(1行) 

コレクション機能の無効化

パフォーマンスを向上させるには、使用していないときに収集機能を無効にします。

alter database postgres set polar_sql_mapping.px_record_query=0;