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

PolarDB:実行プランの調整

最終更新日:Jun 04, 2024

PolarDB for PostgreSQL (Oracleと互換) は、固定実行プランのキャプチャ、表示、および削除を行うアウトライン機能を提供します。

概要

SQLプラン管理 (SPM) は予防メカニズムです。 SPMを使用すると、オプティマイザは実行計画を自動的に管理し、データベースが既知または検証済みの実行計画のみを使用するようにします。

SPMはアウトライン機能を提供します。 アウトライン機能は、固定実行プランのみをサポートします。 アウトライン機能は、進化した実行計画をサポートしていません。 PolarDBのアウトライン機能を使用して、PREPAREステートメントのみの実行計画を固定実行計画としてマークすることができます。

PolarDBのアウトラインフィーチャーは、polar_outline拡張機能を使用して実装されます。 この機能を使用するには、クォータセンターに移動します。 polardb_pg_polar_outlineに対応する [操作] 列で [適用] をクリックします。

polar_outline拡張を作成する

polar_outline拡張機能を作成するには、次のステートメントを実行します。

拡張の作成polar_outline;

パラメーターの設定

アウトライン機能を使用して実行計画を固定実行計画としてマークするには、次のステートメントを実行します。

SET polar_outline.use_stored_planにオン;

Outlineフィーチャによって定義された関数とリレーションは、polar_outlineスキーマに格納されます。 次のステートメントを実行して、polar_outlineスキーマを検索パスに追加できます。

SET search_path "$user",public,polar_outline;

テストデータの準備

次のステートメントを実行して、tという名前のテーブルを作成し、テーブルにデータを挿入します。

CREATE TABLE t(a INT,b INT);
INSERT INTO t SELECT i, i FROM generate_series(1, 1000)i; 

表のデータを更新して、オプティマイザが正確な統計を使用するようにします。

分析t;

PREPAREステートメントを実行します。 以下にコードの例を示します。

PREPAREテストを選択してください * FROM t WHERE a=$1;
説明
  • テストデータは、このセクションの例にのみ適用されます。 ビジネス要件に基づいてステートメントを変更します。
  • アウトライン機能は、キャプチャする実行計画を制御するヒントを提供します。 ステートメントでヒントを使用すると、ステートメントの実行計画がキャプチャされます。 このステートメントをヒントなしで実行すると、このステートメントはキャプチャされた実行プランに基づいて実行されます。

実行計画をキャプチャし、固定計画としてマークする

PolarDB for Oracleは、実行計画をキャプチャし、実行計画を固定実行計画としてマークするための次のメソッドを提供します。

  • polar_outline_create関数を呼び出して、実行プランをキャプチャします。 この方法を使用することを推奨します。 たとえば、次のステートメントを実行します。
    SELECT polar_outline_create('EXECUTE test(100)');

    次の情報が返されます。

    polar_outline_create
    ----------------------
     t
    (1行) 
  • アウトライン機能を使用して実行計画をキャプチャします。 このメソッドを使用すると、複数の実行プランを同時にキャプチャできます。 アウトライン機能を使用して実行計画をキャプチャするには、次の手順を実行します。
    重要 アウトライン機能を使用して実行プランをキャプチャすると、プランキャッシュが生成されます。
    1. 次のステートメントを実行して、アウトライン機能が実行計画をキャプチャできるようにします。
      SET polar_outline.capture_plan to ON;
    2. 次のステートメントを実行して実行プランをキャプチャします。
      Execute test(100);

      次の情報が返されます。

      a | b
      ----- ------
       100 | 100
      (1行) 
    3. アウトライン機能を使用して実行計画をキャプチャしない場合は、次のステートメントを実行します。
      SET polar_outline.capture_plan to OFF;

パラメーター

パラメーター説明
use_stored_planアウトライン機能で実行計画を固定実行計画としてマークできるかどうかを指定します。
  • アウトライン機能で実行計画を固定実行計画としてマークできるようにするには、次のステートメントを実行します。
    SET polar_outline.use_stored_plan To ON;
  • それ以外の場合は、次のステートメントを実行します。
    SET polar_outline.use_stored_plan TO OFF;
capture_planアウトライン機能による実行計画のキャプチャを許可するかどうかを指定します。
  • アウトライン機能が実行計画をキャプチャできるようにするには、次のステートメントを実行します。
    SET polar_outline.capture_plan To ON;
  • それ以外の場合は、次のステートメントを実行します。
    SET polar_outline.capture_plan TO OFF;
log_usage印刷するアウトラインログのレベルを指定します。
set polar_outline.log_usage noneへ;
set polar_outline.log_usageデバッグするには;
polar_outline.log_usageを設定します。polar_outline.log_usageを設定します。polar_outline.log_usageをデバッグ3に設定します。polar_outline.log_usageをデバッグ4に設定します。polar_outline.log_usageを設定します。polar_outline.log_usageを設定します。polar_outline.log_usageを情報に設定します。polar_outline.log_usageを設定します。polar_outline.log_usageを設定する警告; 

アウトライン機能を使用してクエリを書き直す

PolarDBがSQLクエリを書き換えた後にパフォーマンスの問題が発生した場合は、アウトライン機能を使用してSQLクエリを書き換えることができます。
説明 ソースクエリの実行プランが、書き換えられたクエリの実行プランと同等であることを確認します。 そうしないと、PolarDBは誤った実行プランを生成し、誤った結果セットを返す可能性があります。
クエリSQL1の実行プランは, クエリSQL2の実行プランと同じです。
SQL1:
t.a、t2.avg_bを選択
t joinから (avg(b) をavg_bとして選択し、a 
             t2から
             aによるグループ) t2
on t2.a = t.aおよびt.c < $1
t.a; による注文

SQL2:
t.a、t2.avg_bを選択
t join lateralから (avg(b) をavg_bとして選択します)
                     t2から
                     ここで、t2としてt2.a = t.a)
on t.c < $1
注文によるt.a; 

アウトライン機能を使用してSQL1の実行プランをSQL2の実行プランに置き換えるには、次の手順を実行します。

  1. 次のステートメントを実行してデータを準備します。
    CREATE TABLE t(a int, b int, c int);
    insert select i % 100000, i, i from generate_series(1, 1000000) i;
    テーブルt2をselect * from tとして作成します。t(c) にインデックスを作成します。t2(a) にインデックスを作成する。分析t、t2; 
  2. 次のステートメントを実行して、ソースクエリSQL1と書き換えられたクエリSQL2の実行プランをキャプチャします。
    s1をselect t.aとして、t2.avg_bをt joinから準備します (select avg(b) as avg_b, a from t2 group by a) t2。on t2.a = t.aおよびt.c < $1 order by t.a;
    tからselect t.a、t2.avg_bとしてs2を準備し、t2として横方向に結合します (t2.a = t.aであるt2からavg_bとしてavg(b) を選択します) 。on t.c < $1注文によるt.a;
    SELECT polar_outline.polar_outline_create('EXECUTE s1(5)');
     polar_outline_create
    ----------------------
     t
    (1行)
    
    SELECT polar_outline.polar_outline_create('EXECUTE s2(5)');
     polar_outline_create
    ----------------------
     t
    (1行) 
  3. 次のステートメントを実行して、polar_outline_switchを使用して2つのクエリの実行計画を交換します。
    説明 入力パラメーターは、アウトライン内の2つの実行プランのIDです。 SQL1の実行プランがSQL2の実行プランに置き換えられます。
    SELECT polar_outline.polar_outline_switch(1,2);
     polar_outline_switch
    ----------------------
     t
    (1行) 
  4. 次のステートメントを実行して、SQL2の実行プランをアウトラインから削除します。
    説明 SQL1が書き換えられた後、SQL2の実行プランは不要であり、クリアする必要がある。
    SELECT polar_outline.polar_outline_delete(2);
  5. 次のコードは、SQL1が書き換えられる前のSQL1の実行結果と、SQL1が書き換えられた後のSQL1の実行結果を示しています
    。
    EXPLAIN (コストが間違っている) EXECUTE s1(5);
                    クエリ計画
    -------------------------------------------
     ソート
       ソートキー: t.a
       -> ハッシュ参加
             ハッシュコンド :( t.a = t2.a)
             -> tのt_c_idxを使用したインデックススキャン
                   Index Cond :( c < $1)
             ->  Hash
                   -> HashAggregate
                         グループキー: t2.a
                         -> t2のSeqスキャン
    (10行)
    
    SELECT polar_outline_switch(1,2);
     polar_outline_switch
    ----------------------
     t
    (1行)
    
    SQL1が書き換えられた後、s1はSQL1の現在の実行プランを示す。 現在の実行計画はSQL2から供給される。
    EXPLAIN (コストが間違っている) EXECUTE s1(5);
                          クエリ計画
    -------------------------------------------------------
     ソート
       ソートキー: t.a
       -> 入れ子ループ
             -> tのt_c_idxを使用したインデックススキャン
                   Index Cond :( c < $1)
             -> 集約
                   -> t2のビットマップヒープスキャン
                         Recheck Cond :( a = t.a)
                         -> t2_a_idxのビットマップインデックススキャン
                               Index Cond :( a = t.a)
    (10行)