

# Aurora PostgreSQL のクエリ実行計画の管理
<a name="AuroraPostgreSQL.Optimize"></a>

Aurora PostgreSQL クエリプラン管理は、Amazon Aurora の PostgreSQL 互換エディション DB クラスターで使用できるオプション機能です。この機能は、Aurora PostgreSQL DB クラスターにインストールできる `apg_plan_mgmt` エクステンションとしてパッケージ化されています。クエリプラン管理により、SQL アプリケーションについてオプティマイザによって生成されたクエリ実行プランを管理できます。`apg_plan_mgmt` AWS エクステンションは、PostgreSQL データベースエンジンのネイティブクエリ処理機能をベースにしています。

Aurora PostgreSQL クエリプラン管理機能、設定方法、Aurora PostgreSQL DB クラスターでの使用方法について、以下で説明します。始める前に、お使いの Aurora PostgreSQL バージョンで使用可能な特定のバージョンの `apg_plan_mgmt` エクステンションのリリースノートを確認することをお勧めします。詳細については、『*Aurora PostgreSQL リリースノート*』の「[Aurora PostgreSQL apg\$1plan\$1mgmt エクステンションのバージョン](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Extensions.html#AuroraPostgreSQL.Extensions.apg_plan_mgmt)」を参照してください。

**Topics**
+ [Aurora PostgreSQL のクエリプラン管理の概要](AuroraPostgreSQL.Optimize.overview.md)
+ [Aurora PostgreSQL クエリ計画管理のベストプラクティス](AuroraPostgreSQL.Optimize.BestPractice.md)
+ [Aurora PostgreSQL クエリ計画管理](AuroraPostgreSQL.Optimize.Start.md)
+ [Aurora PostgreSQL 実行計画のキャプチャ](AuroraPostgreSQL.Optimize.CapturePlans.md)
+ [Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)
+ [dba\$1plans ビューで Aurora PostgreSQL クエリ計画を検証する](AuroraPostgreSQL.Optimize.ViewPlans.md)
+ [Aurora PostgreSQL クエリ計画の改善](AuroraPostgreSQL.Optimize.Maintenance.md)
+ [Aurora PostgreSQL クエリ計画の削除](AuroraPostgreSQL.Optimize.Deleting.md)
+ [Aurora PostgreSQL の管理計画のエクスポートとインポート](AuroraPostgreSQL.Optimize.Maintenance.ExportingImporting.md)
+ [Aurora PostgreSQL クエリ計画管理のパラメータリファレンス](AuroraPostgreSQL.Optimize.Parameters.md)
+ [Aurora PostgreSQL クエリ計画管理の関数リファレンス](AuroraPostgreSQL.Optimize.Functions.md)
+ [Aurora PostgreSQL 互換エディションの apg\$1plan\$1mgmt.dba\$1plans ビューのリファレンス](AuroraPostgreSQL.Optimize.dba_plans_view_Reference.md)
+ [クエリ計画管理の高度な機能](AuroraPostgreSQL.QPM.Advanced.md)

# Aurora PostgreSQL のクエリプラン管理の概要
<a name="AuroraPostgreSQL.Optimize.overview"></a>

Aurora PostgreSQL クエリプラン管理は、クエリプランのリグレッションを引き起こす可能性のあるデータベースの変更に関係なく、計画の安定性を確保するように設計されています。*クエリプランのリグレッション*は、システムまたはデータベースが変更された後に、オプティマイザが特定の SQL ステートメントに対して最適ではない計画を選択したときに発生します。統計情報、制限事項、環境設定、クエリパラメータのバインディングの変更、PostgreSQL データベースエンジンのアップグレードは、すべて計画のリグレッションの原因になる可能性があります。

Aurora PostgreSQL のクエリプラン管理を使用すると、クエリ実行計画の変更方法と変更時期を制御できます。Aurora PostgreSQL クエリプラン管理には次のような利点があります。
+ オプティマイザに、問題のないことがわかっている少数の計画から強制的に選択させることで、計画の安定性を改善する。
+ 計画を一元的に最適化してから、最善の計画を全体に配布する。
+ 使用されていないインデックスを特定し、インデックスの作成または削除の影響を評価する。
+ オプティマイザが発見した、新しい最小コスト計画を自動的に検出する。
+ パフォーマンスを改善する計画変更のみが承認されるように選択し、新しいオプティマイザの機能を少ないリスクで試す。

クエリプラン管理が提供するツールを積極的に使用して、特定のクエリに最適な計画を指定できます。または、クエリプラン管理を使用して、変化する状況に対応し、計画のリグレッションを回避することもできます。詳細については、「[Aurora PostgreSQL クエリ計画管理のベストプラクティス](AuroraPostgreSQL.Optimize.BestPractice.md)」を参照してください。

**Topics**
+ [サポートされている SQL ステートメント](#AuroraPostgreSQL.Optimize.overview.features)
+ [クエリプラン管理の制限事項](#AuroraPostgreSQL.Optimize.overview.limitations)
+ [クエリプラン管理用語](#AuroraPostgreSQL.Optimize.Start-terminology)
+ [Aurora PostgreSQL クエリプラン管理のバージョン](#AuroraPostgreSQL.Optimize.overview.versions)
+ [Aurora PostgreSQL のクエリプラン管理をオンにする](#AuroraPostgreSQL.Optimize.Enable)
+ [Aurora PostgreSQL のクエリ計画管理アップグレードする](#AuroraPostgreSQL.Optimize.Upgrade)
+ [Aurora PostgreSQL のクエリプラン管理をオフにする](#AuroraPostgreSQL.Optimize.Enable.turnoff)

## サポートされている SQL ステートメント
<a name="AuroraPostgreSQL.Optimize.overview.features"></a>

クエリプラン管理は、次のタイプの SQL ステートメントをサポートします。
+ 複雑性に関係なく、任意の SELECT、INSERT、UPDATE、DELETE ステートメント。
+ プリペアドステートメント。詳細については、PostgreSQL のドキュメントの「[PREPARE](https://www.postgresql.org/docs/14/sql-prepare.html)」を参照してください。
+ 動的ステートメント (即時モードで実行されるものを含む)。詳細については、PostgreSQL ドキュメントの「[動的 SQL](https://www.postgresql.org/docs/current/ecpg-dynamic.html)」と「[EXECUTE IMMEDIATE](https://www.postgresql.org/docs/current/ecpg-sql-execute-immediate.html)」を参照してください。
+ 埋め込み SQL コマンドとステートメント。詳細については、PostgreSQL ドキュメントの「[埋め込み SQL コマンド](https://www.postgresql.org/docs/current/ecpg-sql-commands.html)」を参照してください。
+ 名前付き関数内のステートメント。詳細については、PostgreSQL のドキュメントの「[CREATE FUNCTION](https://www.postgresql.org/docs/current/sql-createfunction.html)」を参照してください。
+ 一時テーブルを含むステートメント。
+ プロシージャと DO ブロック内のステートメント。

クエリプラン管理を `EXPLAIN` と手動モードで使用すると、実際に実行しなくてもプランをキャプチャできます。詳細については、「[オプティマイザが選択した計画の分析](AuroraPostgreSQL.Optimize.UsePlans.md#AuroraPostgreSQL.Optimize.UsePlans.AnalyzePlans)」を参照してください。クエリプラン管理のモード (手動、自動) の詳細については、「[Aurora PostgreSQL 実行計画のキャプチャ](AuroraPostgreSQL.Optimize.CapturePlans.md)」を参照してください。

Aurora PostgreSQL クエリプラン管理は、パーティショニングされたテーブル、継承、行レベルセキュリティ、再帰的なテーブル共通表現 (CTE) など、PostgreSQL のすべての言語機能をサポートします。これらの PostgreSQL 言語機能の詳細については、PostgreSQL ドキュメントの「[テーブルパーティショニング](https://www.postgresql.org/docs/current/ddl-partitioning.html)」、「[行セキュリティポリシー](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)」、「[WITH クエリ (共通テーブル式)](https://www.postgresql.org/docs/current/queries-with.html) 」およびその他のトピックを参照してください。

Aurora PostgreSQL のクエリプラン管理機能のさまざまなバージョンの詳細については、『*Aurora PostgreSQL のリリースノート*』の「[Aurora PostgreSQL apg\$1plan\$1mgmt 拡張機能バージョン](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Extensions.html#AuroraPostgreSQL.Extensions.apg_plan_mgmt)」を参照してください。

## クエリプラン管理の制限事項
<a name="AuroraPostgreSQL.Optimize.overview.limitations"></a>

Aurora PostgreSQL のクエリプラン管理の現在のリリースには、次のような制限があります。
+ **システムリレーションを参照するステートメントのプランはキャプチャされません**。`pg_class` など、システムリレーションを参照するステートメントはキャプチャされません。これは設計によるものであり、内部で使用される多数のシステム生成計画がキャプチャされないようにするためです。これはシステムテーブル内部ビューにも当てはまります。
+ **Aurora PostgreSQL DB クラスターには、より大きな DB インスタンスクラスが必要になる場合があります**。ワークロードによっては、クエリプラン管理に 3 つ以上の vCPU を持つ DB インスタンスクラスが必要になる場合があります。`max_worker_processes` の数は、DB インスタンスクラスのサイズによって制限されます。2 vCPU の DB インスタンスクラス (db.t3.medium など) によって提供される `max_worker_processes` の数は、特定のワークロードに対して十分ではない場合があります。クエリプラン管理を使用する場合は、Aurora PostgreSQL DB クラスター用に 3 つ以上の vCPU を備えた DB インスタンスクラスを選択することをお勧めします。

  DB インスタンスクラスがワークロードをサポートできないと、クエリプラン管理は次のようなエラーメッセージをレイズします。

  ```
  WARNING: could not register plan insert background process
  HINT: You may need to increase max_worker_processes.
  ```

  この場合、Aurora PostgreSQL DB クラスターを、より多くのメモリを搭載した DB インスタンスクラスのサイズにスケールアップする必要があります。詳細については、「[DB インスタンスクラスでサポートされている DB エンジン](Concepts.DBInstanceClass.SupportAurora.md)」を参照してください。
+ **セッションに既に保存されているプランは影響を受けません**。クエリプラン管理を使用すると、アプリケーションコードを変更せずにクエリプランに影響を与えることができます。ただし、ジェネリックプランが既存のセッションに既に保存されていて、そのクエリプランを変更する場合は、まず、DB クラスターパラメータグループで `plan_cache_mode` を`force_custom_plan` に設定する必要があります。
+ 次の場合、`apg_plan_mgmt.dba_plans` と `pg_stat_statements` の `queryid` は異なる可能性があります。
  + オブジェクトが apg\$1plan\$1mgmt.dba\$1plan に保存された後、削除され、再作成されたとき。
  + `apg_plan_mgmt.plans` テーブルが別のクラスターからインポートされたとき。

Aurora PostgreSQL のクエリプラン管理機能のさまざまなバージョンの詳細については、『*Aurora PostgreSQL のリリースノート*』の「[Aurora PostgreSQL apg\$1plan\$1mgmt 拡張機能バージョン](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Extensions.html#AuroraPostgreSQL.Extensions.apg_plan_mgmt)」を参照してください。

## クエリプラン管理用語
<a name="AuroraPostgreSQL.Optimize.Start-terminology"></a>

このトピックでは、次の用語を使用します。

**マネージドステートメント**  
クエリプラン管理でオプティマイザにより取得された SQL ステートメントです。マネージドステートメントには、`apg_plan_mgmt.dba_plans` ビューに 1 つ以上のクエリ実行計画が格納されています。

**計画ベースライン**  
特定のマネージドステートメントで承認された計画のセット。つまり、`dba_plan` ビュー内の `status` 列が「承認済み」になっているマネージドステートメントのすべての計画です。

**計画履歴**  
特定のマネージドステートメント用に取得された一連のすべての計画。計画履歴には、ステータスに関係なく、ステートメントにキャプチャされたすべての計画が含まれます。

**クエリプランのリグレッション**  
オプティマイザが、新しい PostgreSQL バージョンや統計の変更など、データベース環境への特定の変更前よりも最適でない計画を選択した場合。

## Aurora PostgreSQL クエリプラン管理のバージョン
<a name="AuroraPostgreSQL.Optimize.overview.versions"></a>

クエリプラン管理は、現在の Aurora PostgreSQL リリースで利用可能なすべての Aurora PostgreSQL リリースでサポートされています。詳細な情報については、[Aurora PostgreSQL リリースノート](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Updates.html)」の「*Amazon Aurora PostgreSQL の更新*」のリストを参照してください。

`apg_plan_mgmt` 拡張機能をインストールすると、クエリプラン管理機能が Aurora PostgreSQL DB クラスターに追加されます。Aurora PostgreSQL の異なるバージョンでは、異なるバージョンの `apg_plan_mgmt` 拡張機能がサポートされます。クエリプラン管理拡張機能を、ご使用の Aurora PostgreSQL バージョンの最新リリースにアップグレードすることをお勧めします。

**注記**  
各 `apg_plan_mgmt` の拡張機能バージョンのリリースノートについては、*Aurora PostgreSQL のリリースノート*の [Aurora PostgreSQL apg\$1plan\$1mgmt 拡張機能バージョン](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Extensions.html#AuroraPostgreSQL.Extensions.apg_plan_mgmt)を参照してください。

クラスターで実行されているバージョンを特定するには、`psql` を使用してインスタンスに接続し、メタコマンド \$1 dx を使用して次に示すように拡張機能を一覧表示します。

```
labdb=> \dx
                       List of installed extensions
     Name      | Version |    Schema     |                            Description
---------------+---------+---------------+-------------------------------------------------------------------
 apg_plan_mgmt | 1.0     | apg_plan_mgmt | Amazon Aurora with PostgreSQL compatibility Query Plan Management
 plpgsql       | 1.0     | pg_catalog    | PL/pgSQL procedural language
(2 rows)
```

出力は、このクラスターがエクステンションの 1.0 バージョンを使用していることを示しています。特定の Aurora PostgreSQL バージョンで使用できるのは特定の `apg_plan_mgmt` バージョンのみです。場合によっては、Aurora PostgreSQL DB クラスターを新しいマイナーリリースにアップグレードするか、最新バージョンのクエリプラン管理にアップグレードできるようにパッチを適用する必要があります。出力に表示される `apg_plan_mgmt` バージョン 1.0 は Aurora PostgreSQL バージョン 10.17 DB クラスターのもので、新しいバージョンの `apg_plan_mgmt` は利用できません。この場合、Aurora PostgreSQL DB クラスターをより新しいバージョンの PostgreSQL にアップグレードする必要があります。

Aurora PostgreSQL DB クラスターの新しいバージョンの PostgreSQL へのアップグレードの詳細については、「[Amazon Aurora PostgreSQL のデータベースエンジンの更新](AuroraPostgreSQL.Updates.md)」を参照してください。

`apg_plan_mgmt` 拡張機能のアップグレード方法については、[Aurora PostgreSQL のクエリ計画管理アップグレードする](#AuroraPostgreSQL.Optimize.Upgrade) を参照してください。

## Aurora PostgreSQL のクエリプラン管理をオンにする
<a name="AuroraPostgreSQL.Optimize.Enable"></a>

Aurora PostgreSQL DB クラスターのクエリプラン管理を設定するには、拡張機能をインストールし、いくつかの DB クラスターパラメータ設定を変更する必要があります。`apg_plan_mgmt` 拡張機能をインストールし、Aurora PostgreSQL DB クラスターの機能を有効にする `rds_superuser` 権限が必要です。

拡張機能をインストールすると、新しいロール `apg_plan_mgmt` が作成されます。このロールにより、データベースユーザーはクエリプランを表示、管理、および管理できます。`rds_superuser` 権限を持つ管理者として、必要に応じてデータベースユーザーに `apg_plan_mgmt` ロールを付与してください。

次の手順を完了できるのは、`rds_superuser` ロールを持つユーザーのみです。`rds_superuser` は、`apg_plan_mgmt` エクステンションとその `apg_plan_mgmt` ロールの作成に必要です。`apg_plan_mgmt` エクステンションを管理するには、ユーザーに `apg_plan_mgmt` ロールを付与する必要があります。

**Aurora PostgreSQL DB クラスターのクエリプラン管理をオンにするには**

以下のステップでは、Aurora PostgreSQL DB クラスターに送信されるすべての SQL ステートメントのクエリプラン管理を有効にします。これは*自動*モードと呼ばれます。モードの違いについての詳細は、「[Aurora PostgreSQL 実行計画のキャプチャ](AuroraPostgreSQL.Optimize.CapturePlans.md)」を参照してください。

1. Amazon RDS コンソール ([https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)) を開きます。

1. Aurora PostgreSQL DB クラスターに使用する DB クラスターパラメータグループを作成します。クエリプラン管理を有効にし、その動作を設定するには、特定のパラメータを変更する必要があります。詳細については、「[Amazon Aurora での DB パラメータグループの作成](USER_WorkingWithParamGroups.Creating.md)」を参照してください。

1. 次の画像に示すように、カスタム DB クラスターパラメータグループを開き、`rds.enable_plan_management` パラメータを `1` に設定します。  
![\[DB クラスターパラメータグループの画像。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/images/aurora-qpm-custom-db-cluster-param-change-1.png)

   詳細については、「[Amazon Aurora での DB クラスターパラメータグループのパラメータの変更](USER_WorkingWithParamGroups.ModifyingCluster.md)」を参照してください。

1. インスタンスレベルでクエリプランパラメータを設定するために使用できるカスタム DB パラメータグループを作成します。詳細については、「[Amazon Aurora での DB クラスターパラメータグループの作成](USER_WorkingWithParamGroups.CreatingCluster.md)」を参照してください。

1. Aurora PostgreSQL DB クラスターのライターインスタンスを変更して、カスタム DB パラメータグループを使用します。詳細については、「[DB クラスター内の DB インスタンスの変更](Aurora.Modifying.md#Aurora.Modifying.Instance)」を参照してください。

1. カスタム DB パラメータグループを使用するには、Aurora PostgreSQL DB クラスターを変更します。詳細については、「[コンソール、CLI、API を使用した DB クラスターの変更](Aurora.Modifying.md#Aurora.Modifying.Cluster)」を参照してください。

1. DB インスタンスを再起動してカスタムパラメータグループ設定を有効にします。

1. `psql` または `pgAdmin` を使用して Aurora PostgreSQL DB クラスターの DB インスタンスエンドポイントに接続します。次の例では、`postgres` ロールにデフォルトの `rds_superuser` アカウントを使用しています。

   ```
   psql --host=cluster-instance-1.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=my-db
   ```

1. 次に示すように、DB インスタンス用の `apg_plan_mgmt` エクステンションを作成します。

   ```
   labdb=> CREATE EXTENSION apg_plan_mgmt;
   CREATE EXTENSION
   ```
**ヒント**  
アプリケーションのテンプレートデータベースに `apg_plan_mgmt` エクステンションをインストールします。デフォルトのテンプレートデータベースは、`template1` という名前です。詳細については、PostgreSQL ドキュメントの「[テンプレートデータベース](https://www.postgresql.org/docs/current/manage-ag-templatedbs.html)」を参照してください。

1. `apg_plan_mgmt.capture_plan_baselines` パラメータを `automatic` に変更します。この設定では、オプティマイザは、2 回以上計画または実行されるすべての SQL ステートメントのプランを生成します。
**注記**  
クエリプラン管理には、特定の SQL ステートメントに使用できる*手動*モードもあります。詳細については[Aurora PostgreSQL 実行計画のキャプチャ](AuroraPostgreSQL.Optimize.CapturePlans.md)を参照してください。

1. `apg_plan_mgmt.use_plan_baselines` パラメータの値を「オン」に変更します。このパラメータを指定すると、オプティマイザは計画ベースラインからステートメントの計画を選択します。詳細については[Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)を参照してください。
**注記**  
インスタンスを再起動しなくても、セッションのこれらの動的パラメータのいずれかの値を変更できます。

クエリプラン管理の設定が完了したら、クエリプランを表示、管理、または維持する必要があるすべてのデータベースユーザーに `apg_plan_mgmt` ロールを必ず付与してください。

## Aurora PostgreSQL のクエリ計画管理アップグレードする
<a name="AuroraPostgreSQL.Optimize.Upgrade"></a>

クエリプラン管理拡張機能を、ご使用の Aurora PostgreSQL バージョンの最新リリースにアップグレードすることをお勧めします。

1. `rds_superuser` 権限があるユーザーとして、Aurora PostgreSQL DB クラスターのライターインスタンスに接続します。インスタンスの設定時にデフォルトの名前を保持している場合は、`postgres` として接続します。次の例では、`psql` の使用方法を示していますが、希望に応じて pgAdmin を使用することもできます。

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

1. 拡張機能をアップグレードするには、次のクエリを実行します。

   ```
   ALTER EXTENSION apg_plan_mgmt UPDATE TO '2.1';
   ```

1. [apg\$1plan\$1mgmt.validate\$1plans](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.validate_plans) 関数を使用して、すべての計画のハッシュを更新します。オプティマイザは、承認済み、未承認、拒否済みのすべての計画を検証して、新しいバージョンの拡張機能でも引き続き実行可能な計画であることを確認します。

   ```
   SELECT apg_plan_mgmt.validate_plans('update_plan_hash');
   ```

   この関数の使用の詳細については、「[計画の検証](AuroraPostgreSQL.Optimize.Deleting.md#AuroraPostgreSQL.Optimize.Maintenance.ValidatingPlans)」を参照してください。

1. [apg\$1plan\$1mgmt.reload](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.reload) 関数を使用して、共有メモリ内のすべての計画を dba\$1plans ビューからの検証済み計画で更新します。

   ```
   SELECT apg_plan_mgmt.reload();
   ```

クエリプラン管理に使用できるすべての機能の詳細については、「[Aurora PostgreSQL クエリ計画管理の関数リファレンス](AuroraPostgreSQL.Optimize.Functions.md) 」を参照してください。

## Aurora PostgreSQL のクエリプラン管理をオフにする
<a name="AuroraPostgreSQL.Optimize.Enable.turnoff"></a>

クエリプラン管理は、`apg_plan_mgmt.use_plan_baselines` および `apg_plan_mgmt.capture_plan_baselines` をオフにすることで、いつでも無効にできます。

```
labdb=> SET apg_plan_mgmt.use_plan_baselines = off;

labdb=> SET apg_plan_mgmt.capture_plan_baselines = off;
```

# Aurora PostgreSQL クエリ計画管理のベストプラクティス
<a name="AuroraPostgreSQL.Optimize.BestPractice"></a>

クエリ計画管理を使用すると、クエリ実行計画の変更方法と変更時期を制御できます。DBA として、QPM を使用する際の主な目標は、データベースに変更があったときのリグレッションの防止と、オプティマイザが新しい計画を使用できるかどうかの制御です。クエリ計画管理の使用に関する推奨されるベストプラクティスについて、以下に示します。事前予防型および事後対応型の計画管理アプローチでは、新しい計画の使用を承認する方法とタイミングが異なります。

**Contents**
+ [パフォーマンス低下を防止する事前予防型の計画管理](#AuroraPostgreSQL.Optimize.BestPractice.Proactive)
  + [メジャーバージョンのアップグレード後の計画の安定性の確保](#AuroraPostgreSQL.Optimize.BestPractice.MajorVersionUpgrade)
+ [パフォーマンス低下を検出して修復する事後対応型の計画管理](#AuroraPostgreSQL.Optimize.BestPractice.Reactive)

## パフォーマンス低下を防止する事前予防型の計画管理
<a name="AuroraPostgreSQL.Optimize.BestPractice.Proactive"></a>

計画のパフォーマンス低下を防止するには、新しく検出された計画のパフォーマンスを、承認済み計画の既存のベースラインのパフォーマンスと比較し、最速の計画セットを新しいベースラインとして自動的に承認する手順を実行して、計画ベースラインを進化させます**。このように、より速い計画が検出されるにつれて、時間とともに計画のベースラインが改善されます。

1. 開発環境で、パフォーマンスまたはシステムのスループットに最も大きな影響を与える SQL ステートメントを特定します。その後、[特定の SQL ステートメントの計画の手動取り込み](AuroraPostgreSQL.Optimize.CapturePlans.md#AuroraPostgreSQL.Optimize.CapturePlans.Manual) と [自動的な計画の取得](AuroraPostgreSQL.Optimize.CapturePlans.md#AuroraPostgreSQL.Optimize.CapturePlans.Automatic) の説明に従ってこれらのステートメントの計画を取得します。

1. 取得した計画を開発環境からエクスポートし、それらを実稼働環境にインポートします。詳細については、「[Aurora PostgreSQL の管理計画のエクスポートとインポート](AuroraPostgreSQL.Optimize.Maintenance.ExportingImporting.md)」を参照してください。

1. 実稼働環境で、アプリケーションを実行し、承認された管理計画の使用を強制します。詳細については、「[Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)」を参照してください。アプリケーションの実行中にオプティマイザが新しい計画を発見したときは、それらも追加します。詳細については、「[自動的な計画の取得](AuroraPostgreSQL.Optimize.CapturePlans.md#AuroraPostgreSQL.Optimize.CapturePlans.Automatic)」を参照してください。

1. 未承認の計画を分析し、適切に機能する計画を承認します。詳細については、「[計画パフォーマンスの評価](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance)」を参照してください。

1. アプリケーションが継続して実行されている間、オプティマイザは必要に応じて新しい計画を使用し始めます。

### メジャーバージョンのアップグレード後の計画の安定性の確保
<a name="AuroraPostgreSQL.Optimize.BestPractice.MajorVersionUpgrade"></a>

PostgreSQL の各メジャーバージョンには、パフォーマンスを向上させるために設計されたクエリオプティマイザの機能強化と変更が含まれています。ただし、以前のバージョンでオプティマイザーによって生成されたクエリ実行プランは、アップグレードされた新しいバージョンではパフォーマンスが低下する可能性があります。クエリプラン管理を使用して、これらのパフォーマンス問題を解決し、メジャーバージョンアップグレード後のプランの安定性を確保できます。

オプティマイザは、同じステートメントに承認されたプランが複数存在していても、常に最小コストのプランを使用します。アップグレード後、オプティマイザは新しいプランを検出する場合がありますが、それらは未承認プランとして保存されます。これらのプランは、unapproved\$1plan\$1execution\$1threshold パラメータによるリアクティブスタイルのプラン管理を使用して承認された場合にのみ実行されます。evolve\$1plan\$1baselines パラメータを使ったプロアクティブスタイルのプラン管理を使用すると、プランの安定性を最大限に高めることができます。これにより、新しいプランと古いプランのパフォーマンスが比較され、次善のプランよりも 10% 以上早いプランが承認または却下されます。

アップグレード後、`evolve_plan_baselines` 関数を使用して、クエリパラメータをバインドしながらアップグレード前とアップグレード後のプランのパフォーマンスを比較できます。以下のステップでは、「[Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)」で説明されているように、実稼働環境で承認済みのマネージドプランを使用していることを前提としています。

1. アップグレードする前に、クエリプランマネージャーを実行している状態でアプリケーションを実行します。アプリケーションの実行中にオプティマイザが新しいプランを発見したときは、それらも追加します。詳細については、「[自動的な計画の取得](AuroraPostgreSQL.Optimize.CapturePlans.md#AuroraPostgreSQL.Optimize.CapturePlans.Automatic)」を参照してください。

1. 各プランのパフォーマンスを評価します。詳細については、「[計画パフォーマンスの評価](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance)」を参照してください。

1. アップグレード後、`evolve_plan_baselines` 関数を使用して、承認済みのプランを再度分析します。クエリパラメータバインディングの使用前後のパフォーマンスを比較します。新しいプランが速い場合は、承認済みのプランに追加できます。同じパラメータバインディングの別のプランよりも速い場合は、遅いプランを「拒否」としてマークできます。

   詳細については、「[より優れた計画の承認](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance.Approving)」を参照してください。この関数の詳細については、「[apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines)」を参照してください。

詳細については、「[Amazon Aurora PostgreSQL 互換エディションのクエリ計画管理により、メジャーバージョンのアップグレード後に一貫したパフォーマンスを確保する](https://aws.amazon.com/blogs/database/ensuring-consistent-performance-after-major-version-upgrades-with-amazon-aurora-postgresql-query-plan-management/)」を参照してください。

**注記**  
論理レプリケーションまたはを使用してメジャーバージョンアップグレードを実行する場合はAWS DMS、アップグレードしたインスタンスに既存のプランが確実にコピーされるように、`apg_plan_mgmt`スキーマを必ず複製してください。論理レプリケーションの詳細については、「[論理レプリケーションを使用して Aurora PostgreSQL のメジャーバージョンアップグレードを実行する](AuroraPostgreSQL.MajorVersionUpgrade.md)」を参照してください。

## パフォーマンス低下を検出して修復する事後対応型の計画管理
<a name="AuroraPostgreSQL.Optimize.BestPractice.Reactive"></a>

アプリケーションの実行をモニタリングすることによって、パフォーマンスの低下を引き起こす計画を検出できます。パフォーマンス低下を検出したときは、以下のステップに従って、不適切な計画を手動で拒否または修正します。

1. アプリケーションの実行中に、管理計画の使用を強制し、新しく検出された計画を未承認として自動的に追加します。詳細については、「[Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)」および「[自動的な計画の取得](AuroraPostgreSQL.Optimize.CapturePlans.md#AuroraPostgreSQL.Optimize.CapturePlans.Automatic)」を参照してください。

1. 実行中のアプリケーションのパフォーマンス低下をモニタリングします。

1. 計画のパフォーマンス低下を発見した場合、計画のステータスを `rejected` に設定します。次に SQL ステートメントを実行する際、オプティマイザは拒否された計画を自動的に無視し、代わりに別の承認済み計画を使用します。詳細については、「[低速な計画の拒否または無効化](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance.Rejecting)」を参照してください。

   場合によっては、不適切な計画を拒否、無効化、削除せずに、修正した方が良いこともあります。計画の改善を試すには、`pg_hint_plan` エクステンションを使用してください。`pg_hint_plan` では、特別なコメントを使用して、オプティマイザに通常の計画作成方法を上書きするよう指示します。詳細については、「[pg\$1hint\$1plan を使用した計画の修正](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.pg_hint_plan)」を参照してください。

# Aurora PostgreSQL クエリ計画管理
<a name="AuroraPostgreSQL.Optimize.Start"></a>

Aurora PostgreSQL DB クラスターのクエリプラン管理を有効にすると、オプティマイザは複数回処理する SQL ステートメントのクエリ実行計画を生成して保存します。オプティマイザは、マネージドステートメントの初期に生成された計画のステータスを常に `Approved` に設定し、`dba_plans` ビューに保存します。

管理ステートメントの一連の承認済み計画は、*計画ベースライン*と呼ばれます。アプリケーションが実行されると、オプティマイザが管理ステートメントに追加の計画を生成することがあります。オプティマイザは、追加でキャプチャされた計画を `Unapproved` ステータスに設定します。

後で、`Unapproved` 計画が正常に機能するかどうかを確認し、`Approved`、`Rejected`、または `Preferred` に変更できます。そのためには、`apg_plan_mgmt.evolve_plan_baselines` 関数または `apg_plan_mgmt.set_plan_status` 関数を使用します。

オプティマイザが SQL ステートメントの計画を生成すると、クエリプラン管理はその計画を `apg_plan_mgmt.plans` テーブルに保存します。`apg_plan_mgmt` ロールが付与されたデータベースユーザーは、`apg_plan_mgmt.dba_plans` ビューをクエリすることで計画の詳細を確認できます。例えば、次のクエリでは、本番環境以外の Aurora PostgreSQL DB クラスターのビューに現在表示されている計画の詳細が一覧表示されます。
+ `sql_hash` — SQL ステートメントの正規化されたテキストのハッシュ値である SQL ステートメントの識別子。
+ `plan_hash` — `sql_hash` と計画のハッシュを組み合わせた一意の識別子。
+ `status` - 計画のステータス。オプティマイザは、承認済みの計画を実行できます。
+ `enabled` — 計画がすぐに使用できる (true) か、使用できない (false) かを示します。
+ `plan_outline` – 実際の実行計画を再作成するために使用された計画の表現。ツリー構造内の演算子は EXPLAIN 出力の演算子にマップされます。

`apg_plan_mgmt.dba_plans` ビューには、計画が最後に使用された日時など、計画のすべての詳細を含むさらに多くの列があります。詳細については、「[Aurora PostgreSQL 互換エディションの apg\$1plan\$1mgmt.dba\$1plans ビューのリファレンス](AuroraPostgreSQL.Optimize.dba_plans_view_Reference.md)」を参照してください。

## 正規化と SQL ハッシュ
<a name="AuroraPostgreSQL.Optimize.Start.hash-and-normalization"></a>

`apg_plan_mgmt.dba_plans` ビューでは、SQL のハッシュ値により管理ステートメントを識別できます。SQL ハッシュは、リテラル値などのいくつかの違いを取り除く SQL ステートメントの正規化表現で計算されます。

各 SQL ステートメントの*正規化*プロセスでは、スペースと大文字と小文字が区別されないため、SQL ステートメントの要点を読んで理解することができます。正規化により、次の項目が削除されるか置き換えられます。
+ 先頭のブロックコメント
+ EXPLAIN キーワードと EXPLAIN オプション、EXPLAIN ANALYZE
+ 末尾のスペース
+ すべてのリテラル

例として、以下のステートメントを見てみましょう。

```
/*Leading comment*/ EXPLAIN SELECT /* Query 1 */ * FROM t WHERE x > 7 AND y = 1; 
```

クエリ計画管理は、このステートメントを次のように正規化します。

```
SELECT /* Query 1 */ * FROM t WHERE x > CONST AND y = CONST; 
```

正規化を使用することで、リテラル値またはパラメータ値のみが異なる可能性がある類似の SQL ステートメントで同じ SQL ハッシュを使用できます。つまり、同じ SQL ハッシュに対して、異なる計画が異なる条件下で最適となる、複数の計画がある可能性があります。

**注記**  
異なるスキーマで使用される単一の SQL ステートメントは、実行時に特定のスキーマにバインドされるため、計画が異なります。プランナーはスキーマバインディングの統計を使用して最適な計画を選択します。

オプティマイザが計画を選択する方法の詳細については、「[Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)」を参照してください。このセクションでは、`EXPLAIN` および `EXPLAIN ANALYZE` の使用方法と、実際に使用される前に計画をプレビューする方法を学ぶことができます。詳細については、「[オプティマイザが選択した計画の分析](AuroraPostgreSQL.Optimize.UsePlans.md#AuroraPostgreSQL.Optimize.UsePlans.AnalyzePlans)」を参照してください。計画を選択するプロセスの概要を示す画像については、「[オプティマイザが実行する計画を選択する方法。](AuroraPostgreSQL.Optimize.UsePlans.md#AuroraPostgreSQL.Optimize.UsePlans.ChoosePlans)」を参照してください。

# Aurora PostgreSQL 実行計画のキャプチャ
<a name="AuroraPostgreSQL.Optimize.CapturePlans"></a>

Aurora PostgreSQL クエリプラン管理には、自動と手動の 2 つの異なるクエリ実行計画のキャプチャモードが用意されています。`apg_plan_mgmt.capture_plans_baselines` を `automatic` に、または `manual` に設定してモードを選択します。特定の SQL ステートメントの実行計画を取り込むには、手動計画取り込みを使用します。または、自動計画取り込みを使用して、アプリケーションの実行時に 2 回以上実行されるすべての (または最も遅い) 計画を取得することもできます。

オプティマイザは計画取り込み時に、管理ステートメントの初期に取得された計画のステータスを `approved` に設定します。オプティマイザは、管理ステートメント用に取得されたすべての追加の計画のステータスを `unapproved` に設定します。ただし、複数の計画が `approved` ステータスで保存される場合があります。例えば、1 つのステートメントに対して複数の計画が並行して作成された場合や、そのステートメントの初期の計画がコミットされる前に発生する可能性があります。

`dba_plans` ビューに取得して保管できる計画の最大数を制御するには、DB インスタンスレベルのパラメータグループで `apg_plan_mgmt.max_plans` パラメータを設定します。`apg_plan_mgmt.max_plans` パラメータを変更した場合、新しい値を有効にするために DB インスタンスを再起動する必要があります。詳細については、[apg\$1plan\$1mgmt.max\$1plans](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.max_plans) パラメータを参照してください。

## 特定の SQL ステートメントの計画の手動取り込み
<a name="AuroraPostgreSQL.Optimize.CapturePlans.Manual"></a>

管理が必要な既知の SQL ステートメントがある場合は、ステートメントを SQL スクリプトファイルに入れてから、手動で計画を取得します。以下は、一連の SQL ステートメントに対してクエリ計画を手動で取得する方法を psql を例にとって示しています。

```
psql> SET apg_plan_mgmt.capture_plan_baselines = manual;
psql> \i my-statements.sql 
psql> SET apg_plan_mgmt.capture_plan_baselines = off;
```

各 SQL ステートメントに対して計画を取得した後、オプティマイザは `apg_plan_mgmt.dba_plans` ビューに新しい行を追加します。

EXPLAIN ステートメントまたは EXPLAIN EXECUTE ステートメントを SQL スクリプトファイルで使用することをお勧めします。対象となるすべての計画の取り込みに十分なバリエーションがパラメータ値に含まれていることを確認します。

オプティマイザの最小コスト計画よりも優れた計画がある場合は、オプティマイザでその優れた計画が使用されるようになります。そのためには、オプティマイザのヒントを 1 つ以上指定します。詳細については、「[pg\$1hint\$1plan を使用した計画の修正](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.pg_hint_plan)」を参照してください。`unapproved` 計画と `approved` 計画のパフォーマンスを比較して、承認、拒否、または削除する方法については、「[計画パフォーマンスの評価](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance)」を参照してください。

## 自動的な計画の取得
<a name="AuroraPostgreSQL.Optimize.CapturePlans.Automatic"></a>

以下のような状況では、自動計画キャプチャを使用します。
+ 管理する特定の SQL ステートメントが分からない場合。
+ 管理対象となる SQL ステートメントが数百、数千ある場合。
+ ユーザーのアプリケーションがクライアント API を使用している場合。例えば、JDBC では、psql では表現できない、名前のない準備済みステートメントまたは一括モードのステートメントを使用します。

**自動的に計画を取得するには**

1. DB インスタンスレベルのパラメータグループで `apg_plan_mgmt.capture_plan_baselines` を `automatic` に設定して、自動計画取り込みをオンにします。詳細については、「[Amazon Aurora の DB パラメータグループのパラメータの変更](USER_WorkingWithParamGroups.Modifying.md)」を参照してください。

1. アプリケーションが実行されると、オプティマイザは少なくとも 2 回以上実行される各 SQL ステートメントの計画を取得します。

   デフォルトのクエリ計画管理パラメータ設定を使用してアプリケーションが実行されると、オプティマイザは少なくとも 2 回以上実行される各 SQL ステートメントの計画を取得します。デフォルト設定を使用してすべての計画を取り込むことで、実行時のオーバーヘッドを大幅に削減し、実稼働環境で有効にすることができます。

**自動計画取り込みをオフにするには**
+ DB インスタンスレベルのパラメータグループから `apg_plan_mgmt.capture_plan_baselines` パラメータを `off` に設定します。

未承認の計画のパフォーマンスを測定して、それらを承認、拒否、または削除する方法については、「[計画パフォーマンスの評価](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance)」を参照してください。

# Aurora PostgreSQL 管理計画を使用する
<a name="AuroraPostgreSQL.Optimize.UsePlans"></a>

オプティマイザが管理ステートメントに対して取り込んだ計画を使用するには、パラメータ `apg_plan_mgmt.use_plan_baselines` を `true` に設定します。以下はローカルインスタンスの例です。

```
SET apg_plan_mgmt.use_plan_baselines = true;
```

この設定により、アプリケーションの実行中、オプティマイザでは、管理ステートメントごとに最小コストの計画、推奨される計画または承認済み計画が使用されるようになります。

## オプティマイザが選択した計画の分析
<a name="AuroraPostgreSQL.Optimize.UsePlans.AnalyzePlans"></a>

`apg_plan_mgmt.use_plan_baselines` パラメータが `true` に設定されていれば、EXPLAIN ANALYZE SQL ステートメントを使用して、オプティマイザがステートメントを実行する場合に使用する計画を表示することができます。以下に例を示します。

```
EXPLAIN ANALYZE EXECUTE rangeQuery (1,10000);
```

```
                                                    QUERY PLAN           
--------------------------------------------------------------------------
 Aggregate  (cost=393.29..393.30 rows=1 width=8) (actual time=7.251..7.251 rows=1 loops=1)
   ->  Index Only Scan using t1_pkey on t1 t  (cost=0.29..368.29 rows=10000 width=0) (actual time=0.061..4.859 rows=10000 loops=1)
Index Cond: ((id >= 1) AND (id <= 10000))         
         Heap Fetches: 10000
 Planning time: 1.408 ms
 Execution time: 7.291 ms
 Note: An Approved plan was used instead of the minimum cost plan.
 SQL Hash: 1984047223, Plan Hash: 512153379
```

出力には、実行するベースラインの承認済み計画が表示されます。ただし、出力にはより低コストの計画が見つかったことがわかります。この場合、[自動的な計画の取得](AuroraPostgreSQL.Optimize.CapturePlans.md#AuroraPostgreSQL.Optimize.CapturePlans.Automatic) で説明されているように自動計画取り込みをオンにして、この新しい最小コスト計画を取得します。

新しい計画は常に `Unapproved` としてオプティマイザによってキャプチャされます。計画を比較し、それらを承認済み、拒否、または無効に変更するには、`apg_plan_mgmt.evolve_plan_baselines` 関数を使用します。詳細については、「[計画パフォーマンスの評価](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance)」を参照してください。

## オプティマイザが実行する計画を選択する方法。
<a name="AuroraPostgreSQL.Optimize.UsePlans.ChoosePlans"></a>

実行計画のコストは、オプティマイザが異なる計画を比較するために行う見積もりです。計画のコストを計算する際、オプティマイザではその計画で必要な CPU や I/O オペレーションなどの要素を考慮します。PostgreSQL クエリプランナーのコスト見積もりの詳細については、PostgreSQL のドキュメントの「[Query Planning](https://www.postgresql.org/docs/current/runtime-config-query.html)」(クエリ計画) を参照してください。

次のイメージは、クエリプラン管理が有効な場合とそうでない場合に、特定の SQL ステートメントに対して計画がどのように選択されるかを示しています。



![\[Aurora PostgreSQL のクエリ計画管理ワークフロー\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/images/aurora-query-plan-mgmt_processing-flow.png)


フローは次のとおりです。

1. オプティマイザでは、SQL ステートメントの最小コストの計画が生成されます。

1. クエリ計画管理が有効ではない場合、オプティマイザの計画が直ちに実行されます (A. オプティマイザの計画を実行)。クエリ計画管理は、`apg_plan_mgmt.capture_plan_baselines` と `apg_plan_mgmt.use_plan_baselines` のパラメータがどちらもデフォルト設定 (それぞれ「off」と「false」) の場合は無効になります。

   それ以外の場合は、クエリ計画管理が有効になります。この場合、SQL ステートメントとそれに対するオプティマイザの計画がさらに評価されてから計画が選択されます。
**ヒント**  
`apg_plan_mgmt` ロールのデータベースユーザーは、必要に応じて計画をプロアクティブに比較する、計画のステータスを変更する、特定の計画を強制的に使用することができます。詳細については、「[Aurora PostgreSQL クエリ計画の改善](AuroraPostgreSQL.Optimize.Maintenance.md)」を参照してください。

1. SQL ステートメントには、過去にクエリ計画管理によって保存された計画が既に含まれている場合があります。計画は、その計画の作成に使用された SQL ステートメントに関する情報とともに `apg_plan_mgmt.dba_plans` に保存されます。計画に関する情報には、そのステータスが含まれます。計画のステータスによって、その計画が使用されているかどうかが次のように決まります。

   1. 計画が SQL ステートメントの保存計画に含まれていない場合は、特定の SQL ステートメントのオプティマイザによってこの特定の計画が初めて生成されたことになります。計画は、キャプチャ計画処理 (4) に送信されます。

   1. 計画が保存されている計画の中にあり、ステータスが「承認済み」または「優先」の場合、その計画が実行されます (A. オプティマイザの計画を実行)。

      計画が保存されている計画に含まれていても、承認済みでも優先でもない場合、計画はキャプチャ計画処理 (4) に送信されます。

1. 特定の SQL ステートメントの計画が初めてキャプチャされると、計画のステータスは常に承認済み (P1) に設定されます。その後、オプティマイザが同じ SQL ステートメントに対して同じ計画を生成すると、その計画のステータスは未承認 (P1\$1n) に変更されます。

   計画がキャプチャされ、ステータスが更新されると、次のステップ (5) で評価が継続されます。

1. 計画の*ベースライン*は、さまざまなステータスでの SQL ステートメントの履歴と計画で構成されています。クエリ計画管理では、計画のベースラインを使用するオプションがオンになっているかどうかによって、次のように計画を選択する際にベースラインを考慮できます。
   + 計画ベースラインの使用は「オフ」の場合、`apg_plan_mgmt.use_plan_baselines` パラメータはデフォルト値 (`false`) に設定されています。計画は、実行前にベースラインと比較されません (A. オプティマイザの計画を実行)。
   + 計画ベースラインの使用が「オン」の場合、`apg_plan_mgmt.use_plan_baselines` パラメータは `true` に設定されます。計画はベースライン (6) を使用してさらに評価されます。

1. この計画は、ベースラインのステートメントの他の計画と比較されます。

   1. オプティマイザの計画がベースラインの計画に含まれる場合、そのステータスがチェックされます (7a)。

   1. オプティマイザの計画がベースラインの計画にない場合、その計画は新規の `Unapproved` 計画としてステートメントの計画に追加されます。

1. 未承認の場合のみ、計画のステータスを確認します。

   1. 計画のステータスが [Unapproved] (未承認) の場合、計画のコストの見積もりは、未承認の実行計画のしきい値に指定されたコストの見積もりと比較されます。
      + 計画のコストの見積もりがしきい値を下回る場合、オプティマイザでは [Unapproved] (未承認) の計画であってもその計画を使用します (A. オプティマイザの計画を実行)。通常、オプティマイザは [Unapproved] (未承認) の計画を実行しません。ただし、`apg_plan_mgmt.unapproved_plan_execution_threshold` パラメータでコストのしきい値を指定すると、オプティマイザは [Unapproved] (未承認) の計画のコストをしきい値と比較します。コストの見積もりがしきい値を下回る場合、オプティマイザは計画を実行します。詳細については、「[apg\$1plan\$1mgmt.unapproved\$1plan\$1execution\$1threshold](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.unapproved_plan_execution_threshold)」を参照してください。
      + 計画のコストの見積もりがしきい値を下回っていない場合は、計画の他の属性がチェックされます (8a)。

   1. 計画のステータスが [Unapproved] (未承認) 以外の場合、他の属性が確認されます (8a)。

1. オプティマイザは、無効の計画を使用しません。つまり、`enable` 属性が「f」 (false) に設定されている計画です。また、オプティマイザはステータスが Rejected (拒否) の計画を使用しません。

   オプティマイザは、無効の計画を使用できません。管理計画が依存するオブジェクト (インデックスやテーブルパーティションなど) が削除されると、時間の経過とともに計画が無効になる可能性があります。

   1. ステートメントに有効な推奨計画がある場合、オプティマイザではこの SQL ステートメントに保存されている推奨計画の中から最小コストの計画を選択します。その後、オプティマイザは最小コストの推奨計画を実行します。

   1. そのステートメントに有効化された計画や、有効で推奨される計画がない場合は、次のステップ (9) で評価されます。

1. そのステートメントに有効な推奨計画がある場合、オプティマイザではこの SQL ステートメントに保存されている推奨計画の中から最小コストの計画を選択します。その後、オプティマイザは最小コストの承認済み計画を実行します。

   そのステートメントに有効化された計画や、有効で推奨される計画がない場合、オプティマイザは最小コスト計画 (A. オプティマイザの計画を実行) を使用します。

# dba\$1plans ビューで Aurora PostgreSQL クエリ計画を検証する
<a name="AuroraPostgreSQL.Optimize.ViewPlans"></a>

`apg_plan_mgmt` ロールを付与されたデータベースユーザーと管理者は、`apg_plan_mgmt.dba_plans` に保存されている計画を表示および管理できます。Aurora PostgreSQL DB クラスターの管理者 (`rds_superuser` 権限を持つ人) は、クエリプラン管理を行う必要があるデータベースユーザーにこのロールを明示的に付与する必要があります。

`apg_plan_mgmt` ビューには、Aurora PostgreSQL DB クラスターのライターインスタンス上のすべてのデータベースのあらゆるマネージド SQL ステートメントの計画履歴が含まれます。このビューでは、計画、その状態、最終使用日時、その他すべての関連詳細を確認できます。

「[正規化と SQL ハッシュ](AuroraPostgreSQL.Optimize.Start.md#AuroraPostgreSQL.Optimize.Start.hash-and-normalization)」で説明しているように、管理計画はそれぞれ、SQL ハッシュ値と計画ハッシュ値を組み合わせて識別されます。これらの識別子を使用すると、Amazon RDS Performance Insights などのツールを使用して個別の計画のパフォーマンスを追跡できます。Performance Insights の詳細については、「[Amazon RDS Performance Insights の使用]( https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PerfInsights.html)」を参照してください。

## 管理計画のリスト化
<a name="AuroraPostgreSQL.Optimize.ViewPlans.List"></a>

管理計画をリスト化するには、`apg_plan_mgmt.dba_plans` ビューの SELECT ステートメントを使用します。次の例では、`dba_plans` ビューに、承認済みの計画および未承認の計画を識別する `status` などの列が表示されます。

```
SELECT sql_hash, plan_hash, status, enabled, stmt_name 
FROM apg_plan_mgmt.dba_plans; 

 sql_hash   | plan_hash |   status   | enabled | stmt_name
------------+-----------+------------+---------+------------
 1984047223 | 512153379 | Approved   | t       | rangequery 
 1984047223 | 512284451 | Unapproved | t       | rangequery 
 (2 rows)
```

読みやすくするために、表示されるクエリと出力には、`dba_plans` ビューの一部の列のみがリストされています。詳細については、「[Aurora PostgreSQL 互換エディションの apg\$1plan\$1mgmt.dba\$1plans ビューのリファレンス](AuroraPostgreSQL.Optimize.dba_plans_view_Reference.md)」を参照してください。

# Aurora PostgreSQL クエリ計画の改善
<a name="AuroraPostgreSQL.Optimize.Maintenance"></a>

計画のパフォーマンスと修正計画を評価することで、クエリ計画の管理を改善します。クエリ計画の改善の詳細については、以下のトピックを参照してください。

**Topics**
+ [計画パフォーマンスの評価](#AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance)
+ [pg\$1hint\$1plan を使用した計画の修正](#AuroraPostgreSQL.Optimize.Maintenance.pg_hint_plan)

## 計画パフォーマンスの評価
<a name="AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance"></a>

オプティマイザが計画を未承認として取得した後、`apg_plan_mgmt.evolve_plan_baselines` 関数を使用して、実際のパフォーマンスに基づいて計画を比較します。パフォーマンステストの結果に応じて、計画のステータスを未承認から承認済みまたは拒否に変更できます。要件に合わない場合は、代わりに `apg_plan_mgmt.evolve_plan_baselines` 関数を使用して計画を一時的に無効にすることができます。

### より優れた計画の承認
<a name="AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance.Approving"></a>

以下の例は、`apg_plan_mgmt.evolve_plan_baselines` 関数を使用して、管理計画のステータスを承認済みに変更する方法を示しています。

```
SELECT apg_plan_mgmt.evolve_plan_baselines (
   sql_hash, 
   plan_hash, 
   min_speedup_factor := 1.0, 
   action := 'approve'
) 
FROM apg_plan_mgmt.dba_plans WHERE status = 'Unapproved';
```

```
NOTICE:     rangequery (1,10000)
NOTICE:     Baseline   [ Planning time 0.761 ms, Execution time 13.261 ms]
NOTICE:     Baseline+1 [ Planning time 0.204 ms, Execution time 8.956 ms]
NOTICE:     Total time benefit: 4.862 ms, Execution time benefit: 4.305 ms
NOTICE:     Unapproved -> Approved
evolve_plan_baselines 
-----------------------
0
(1 row)
```

出力は、1 と 10,000 のパラメータのバインディングを持つ `rangequery` ステートメントのパフォーマンス報告を示しています。新しい未承認の計画 (`Baseline+1`) は、以前に承認された最も良い計画 (`Baseline`) よりも優れています。新しい計画が `Approved` になったことを確認するには、`apg_plan_mgmt.dba_plans` ビューをチェックします。

```
SELECT sql_hash, plan_hash, status, enabled, stmt_name 
FROM apg_plan_mgmt.dba_plans;
```

```
sql_hash  | plan_hash |  status  | enabled | stmt_name  
------------+-----------+----------+---------+------------
1984047223 | 512153379 | Approved | t       | rangequery
1984047223 | 512284451 | Approved | t       | rangequery
(2 rows)
```

管理計画には、ステートメントの計画ベースラインである 2 つの承認済み計画が含まれるようになりました。`apg_plan_mgmt.set_plan_status` 関数を呼び出して、計画のステータスフィールドを直接 `'Approved'`、`'Rejected'`、`'Unapproved'`、または `'Preferred'` に設定することもできます。

### 低速な計画の拒否または無効化
<a name="AuroraPostgreSQL.Optimize.Maintenance.EvaluatingPerformance.Rejecting"></a>

計画を拒否または無効化するには、`'reject'` または `'disable' ` をアクションパラメータとして `apg_plan_mgmt.evolve_plan_baselines` 関数に渡します。この例では、ステートメントの最適な `Unapproved` 計画と比較して 10％ 以上低速なキャプチャ済み `Approved` 計画を無効にします。

```
SELECT apg_plan_mgmt.evolve_plan_baselines(
sql_hash,  -- The managed statement ID
plan_hash, -- The plan ID
1.1,       -- number of times faster the plan must be 
'disable'  -- The action to take. This sets the enabled field to false.
)
FROM apg_plan_mgmt.dba_plans
WHERE status = 'Unapproved' AND   -- plan is Unapproved
origin = 'Automatic';       -- plan was auto-captured
```

直接、計画を拒否または無効に設定することもできます。計画の有効フィールドを直接 `true` または `false` に設定するには、`apg_plan_mgmt.set_plan_enabled` 関数を呼び出します。計画のステータスフィールドを直接 `'Approved'`、`'Rejected'`、`'Unapproved'`、または `'Preferred'` に設定するには、`apg_plan_mgmt.set_plan_status` 関数を呼び出します。

有効ではなく、無効のままになると見られる計画を削除するには、`apg_plan_mgmt.validate_plans` 関数を使用します。この関数により、無効な計画を削除または無効にすることができます。詳細については、「[計画の検証](AuroraPostgreSQL.Optimize.Deleting.md#AuroraPostgreSQL.Optimize.Maintenance.ValidatingPlans)」を参照してください。

## pg\$1hint\$1plan を使用した計画の修正
<a name="AuroraPostgreSQL.Optimize.Maintenance.pg_hint_plan"></a>

クエリオプティマイザは、すべてのステートメントに対して最適な計画を見つけるように設計されています。ほとんどの場合、オプティマイザは優れた計画を見つけます。ただし、オプティマイザが生成する計画よりもはるかに優れた計画が存在することがあります。オプティマイザに理想的な計画を生成させるために推奨される 2 つの方法は、`pg_hint_plan` エクステンションを使用すること、または PostgreSQL で Grand Unified Configuration (GUC) 可変を設定することです。
+ `pg_hint_plan` エクステンション - PostgreSQL の `pg_hint_plan` エクステンションを使用して、プランナーの動作を変更するための「ヒント」を指定します。`pg_hint_plan` エクステンションのインストールおよび使用方法の詳細については、「[pg\$1hint\$1plan ドキュメント](https://github.com/ossc-db/pg_hint_plan)」を参照してください。
+ GUC 可変 - 1 つ以上のコストモデルパラメータ、または `from_collapse_limit` や `GEQO_threshold` などの他のオプティマイザパラメータを上書きします。

これらの手法のいずれかを使用してクエリオプティマイザに計画の使用を強制する場合、クエリ計画管理を使用して、新しい計画を取得した後で強制的に使用することもできます。

`pg_hint_plan` エクステンションを使用して、SQL ステートメントの結合の順序、結合メソッド、またはアクセスパスを変更することができます。オプティマイザによる計画の作成方法を変更するには、特別な `pg_hint_plan` 構文を持つ SQL コメントを使用します。例えば、問題のある SQL ステートメントに双方向の結合があるとします。

```
SELECT * 
FROM t1, t2 
WHERE t1.id = t2.id;
```

次に、オプティマイザが結合順序 (t1、t2) を選択したとします。しかし、ユーザーは結合順序 (t2、t1) の方が速いことを知っています。以下のヒントは、より高速な結合順序 (t2、t1) を使用するようオプティマイザに強制します。オプティマイザが SQL ステートメントの計画を生成しても、そのステートメントを実行せずに、EXPLAIN を含めます。(出力は表示されていません。)

```
/*+ Leading ((t2 t1)) */ EXPLAIN SELECT * 
FROM t1, t2 
WHERE t1.id = t2.id;
```

以下のステップは、`pg_hint_plan` の使用方法を示しています。

**オプティマイザの生成した計画を変更し、pg\$1hint\$1plan を使用して計画を取得するには**

1. 手動取り込みモードをオンにします。

   ```
   SET apg_plan_mgmt.capture_plan_baselines = manual;
   ```

1. 目的の SQL ステートメントのヒントを指定してください。

   ```
   /*+ Leading ((t2 t1)) */ EXPLAIN SELECT * 
   FROM t1, t2 
   WHERE t1.id = t2.id;
   ```

   これが実行された後、オプティマイザは `apg_plan_mgmt.dba_plans` ビューで計画をキャプチャします。クエリ計画管理は先頭のコメントを削除することでステートメントを正規化するため、キャプチャされた計画には特別な `pg_hint_plan` コメント構文は含まれません。

1. `apg_plan_mgmt.dba_plans` ビューを使用して管理計画を表示します。

   ```
   SELECT sql_hash, plan_hash, status, sql_text, plan_outline 
   FROM apg_plan_mgmt.dba_plans;
   ```

1. 計画のステータスを `Preferred` に設定します｡ これにより、最小コスト計画がまだ `Approved` や `Preferred` になっていない場合、オプティマイザは一連の承認済み計画から選択せずに、その計画を実行することを選択します。

   ```
   SELECT apg_plan_mgmt.set_plan_status(sql-hash, plan-hash, 'preferred' ); 
   ```

1. 手動計画取り込みをオフにして、管理計画の使用を強制します。

   ```
   SET apg_plan_mgmt.capture_plan_baselines = false;
   SET apg_plan_mgmt.use_plan_baselines = true;
   ```

   これで、元の SQL ステートメントが実行されると、オプティマイザは `Approved` 計画または `Preferred` 計画のいずれかを選択します。最小コスト計画が `Approved` や `Preferred` でない場合、オプティマイザは `Preferred` 計画を選択します。

# Aurora PostgreSQL クエリ計画の削除
<a name="AuroraPostgreSQL.Optimize.Deleting"></a>

使用していない実行計画、または有効でない計画を削除します。計画の削除の詳細については、以下のセクションを参照してください。

**Topics**
+ [計画の削除](#AuroraPostgreSQL.Optimize.Maintenance.DeletingPlans)
+ [計画の検証](#AuroraPostgreSQL.Optimize.Maintenance.ValidatingPlans)

## 計画の削除
<a name="AuroraPostgreSQL.Optimize.Maintenance.DeletingPlans"></a>

計画は、1 か月以上、具体的には 32 日間使用されなかった場合、自動的に削除されます。これは、`apg_plan_mgmt.plan_retention_period` パラメータのデフォルト設定です。計画の保持期間をより長い期間に変更できますが、最小期間は 1 です。計画が最後に使用された日付から、`last_used` の日付を現在の日付から引いて日数を算出します。`last_used` の日付は、オプティマイザが最小コスト計画としてプランを選択したか、プランが実行された最新の日付です。計画の日付は `apg_plan_mgmt.dba_plans` ビューに保存されます。

長期間使用されていない、または有用ではない計画を削除することをお勧めします。すべての計画には `last_used` の日付があり、オプティマイザは計画を実行するたびに更新するか、ステートメントの最小コスト計画として計画を選択します。最後の `last_used` の日付を確認して、安全に削除できる計画を確認してください。

次のクエリは、プランの総数、削除に失敗したプラン、削除に成功したプランの数を含む 3 列のテーブルを返します。`apg_plan_mgmt.delete_plan` 関数を使用して過去 31 日以内に最小コスト計画として選択されておらず、ステータスが `Rejected` ではないすべての計画を削除する方法の例であるネストしたクエリが入っています。

```
SELECT (SELECT COUNT(*) from apg_plan_mgmt.dba_plans) total_plans,
       COUNT(*) FILTER (WHERE result = -1) failed_to_delete,
       COUNT(*) FILTER (WHERE result = 0) successfully_deleted
       FROM (
            SELECT apg_plan_mgmt.delete_plan(sql_hash, plan_hash) as result
            FROM apg_plan_mgmt.dba_plans
            WHERE last_used < (current_date - interval '31 days')
            AND status <> 'Rejected'
            ) as dba_plans ;
```

```
 total_plans | failed_to_delete | successfully_deleted
-------------+------------------+----------------------
           3 |                0 |                    2
```

詳細については、「[apg\$1plan\$1mgmt.delete\$1plan](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.delete_plan)」を参照してください。

有効ではなく、無効のままになると見られる計画を削除するには、`apg_plan_mgmt.validate_plans` 関数を使用します。この関数により、無効な計画を削除または無効にすることができます。詳細については、「[計画の検証](#AuroraPostgreSQL.Optimize.Maintenance.ValidatingPlans)」を参照してください。

**重要**  
無関係な計画を削除しないと、クエリプラン管理用に確保されている共有メモリが不足する可能性があります。マネージド計画に使用可能なメモリー量を制御するには、`apg_plan_mgmt.max_plans` パラメータを使用します。カスタム DB インスタンスのパラメータグループでこのパラメータを設定し、変更を有効にするために DB インスタンスを再起動します。詳細については、[apg\$1plan\$1mgmt.max\$1plans](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.max_plans) パラメータを参照してください。

## 計画の検証
<a name="AuroraPostgreSQL.Optimize.Maintenance.ValidatingPlans"></a>

利用不可能な計画を削除、または無効にするには、`apg_plan_mgmt.validate_plans` 関数を使用します。

管理計画が依存するオブジェクト (インデックスやテーブルなど) が削除されると、計画が利用不可能、または停滞となる可能性があります。ただし、削除されたオブジェクトが再作成されれば、計画が利用不可能なのは一時的です。利用不可能な計画が後で利用可能になる可能性がある場合は、利用不可能な計画を無効にするか、または削除せずに何もしないでいることができます。

利用不可能で、かつ過去 1 週間に使用されていないすべての計画を検索して削除するには、`apg_plan_mgmt.validate_plans ` 関数を以下のように使用します。

```
SELECT apg_plan_mgmt.validate_plans(sql_hash, plan_hash, 'delete') 
FROM apg_plan_mgmt.dba_plans
WHERE last_used < (current_date - interval '7 days');
```

計画を直接有効、または無効にするには、`apg_plan_mgmt.set_plan_enabled` 関数を使用します。

# Aurora PostgreSQL の管理計画のエクスポートとインポート
<a name="AuroraPostgreSQL.Optimize.Maintenance.ExportingImporting"></a>

管理計画をエクスポートしたり、別の DB インスタンスにインポートできます。

**管理計画をエクスポートする**  
承認されたユーザーは `apg_plan_mgmt.plans` テーブルの任意のサブセットを別のテーブルにコピーしてから、`pg_dump` コマンドを使用してそれを保存することができます。次に例を示します。

```
CREATE TABLE plans_copy AS SELECT * 
FROM apg_plan_mgmt.plans [ WHERE predicates ] ;
```

```
% pg_dump --table apg_plan_mgmt.plans_copy -Ft mysourcedatabase > plans_copy.tar
```

```
DROP TABLE apg_plan_mgmt.plans_copy;
```

**管理計画をインポートする**

1. エクスポートした管理計画の .tar ファイルを、計画を復元する予定のシステムにコピーします。

1. tar ファイルを新しいテーブルにコピーするには、`pg_restore` コマンドを使用します。

   ```
   % pg_restore --dbname mytargetdatabase -Ft plans_copy.tar
   ```

1. 次の例に示すように、`plans_copy` テーブルを `apg_plan_mgmt.plans` テーブルとマージします。
**注記**  
場合によっては、あるバージョンの `apg_plan_mgmt` エクステンションからダンプして別のバージョンに復元することがあります。このような場合は、計画テーブルの列が異なる可能性があります。その場合は、SELECT \$1 を使用せず、列に明示的に名前を付けてください。

   ```
   INSERT INTO apg_plan_mgmt.plans SELECT * FROM plans_copy
    ON CONFLICT ON CONSTRAINT plans_pkey
    DO UPDATE SET
    status = EXCLUDED.status,
    enabled = EXCLUDED.enabled,
    -- Save the most recent last_used date 
    --
    last_used = CASE WHEN EXCLUDED.last_used > plans.last_used 
    THEN EXCLUDED.last_used ELSE plans.last_used END, 
    -- Save statistics gathered by evolve_plan_baselines, if it ran:
    --
    estimated_startup_cost = EXCLUDED.estimated_startup_cost,
    estimated_total_cost = EXCLUDED.estimated_total_cost,
    planning_time_ms = EXCLUDED.planning_time_ms,
    execution_time_ms = EXCLUDED.execution_time_ms,
    total_time_benefit_ms = EXCLUDED.total_time_benefit_ms, 
    execution_time_benefit_ms = EXCLUDED.execution_time_benefit_ms;
   ```

1. 管理計画を共有メモリにリロードし、一時的な計画テーブルを削除します。

   ```
   SELECT apg_plan_mgmt.reload(); -- refresh shared memory
   DROP TABLE plans_copy;
   ```

# Aurora PostgreSQL クエリ計画管理のパラメータリファレンス
<a name="AuroraPostgreSQL.Optimize.Parameters"></a>

このセクションに記載されているパラメータを使用して、`apg_plan_mgmt` 拡張機能を設定できます。これらは、カスタム DB クラスターパラメータと Aurora PostgreSQL DB クラスターに関連付けられた DB パラメータグループで使用できます。これらのパラメータは、クエリ計画管理機能の動作と、それがオプティマイザに与える影響を制御します。クエリ計画管理のセットアップの詳細については、「[Aurora PostgreSQL のクエリプラン管理をオンにする](AuroraPostgreSQL.Optimize.overview.md#AuroraPostgreSQL.Optimize.Enable)」を参照してください。次のパラメータを変更しても、`apg_plan_mgmt` 拡張機能はそのセクションで詳述されているように設定されていない場合は効果がありません。パラメータの変更については、「[Amazon Aurora での DB クラスターパラメータグループのパラメータの変更](USER_WorkingWithParamGroups.ModifyingCluster.md)」および「[Amazon Aurora DB インスタンスの DB パラメータグループ](USER_WorkingWithDBInstanceParamGroups.md)」を参照してください。

**Topics**
+ [apg\$1plan\$1mgmt.capture\$1plan\$1baselines](#AuroraPostgreSQL.Optimize.Parameters.capture_plan_baselines)
+ [apg\$1plan\$1mgmt.plan\$1capture\$1threshold](#AuroraPostgreSQL.Optimize.Parameters.plan_capture_threshold)
+ [apg\$1plan\$1mgmt.explain\$1hashes](#AuroraPostgreSQL.Optimize.Parameters.explain_hashes)
+ [apg\$1plan\$1mgmt.log\$1plan\$1Enforcement\$1result](#AuroraPostgreSQL.Optimize.Parameters.log_plan_enforcement_result)
+ [apg\$1plan\$1mgmt.max\$1databases](#AuroraPostgreSQL.Optimize.Parameters.max_databases)
+ [apg\$1plan\$1mgmt.max\$1plans](#AuroraPostgreSQL.Optimize.Parameters.max_plans)
+ [apg\$1plan\$1mgmt.plan\$1hash\$1version](#AuroraPostgreSQL.Optimize.Parameters.plan_hash_version)
+ [apg\$1plan\$1mgmt.plan\$1retention\$1period](#AuroraPostgreSQL.Optimize.Parameters.plan_retention_period)
+ [apg\$1plan\$1mgmt.unapproved\$1plan\$1execution\$1threshold](#AuroraPostgreSQL.Optimize.Parameters.unapproved_plan_execution_threshold)
+ [apg\$1plan\$1mgmt.use\$1plan\$1baselines](#AuroraPostgreSQL.Optimize.Parameters.use_plan_baselines)
+ [auto\$1explain.hashes](#AuroraPostgreSQL.Optimize.Parameters.auto_explain.hashes)

## apg\$1plan\$1mgmt.capture\$1plan\$1baselines
<a name="AuroraPostgreSQL.Optimize.Parameters.capture_plan_baselines"></a>

各 SQL ステートメントのオプティマイザによって生成されたクエリ実行計画をキャプチャし、`dba_plans` ビューに保存します。デフォルトでは、`apg_plan_mgmt.max_plans` パラメータで指定された保存可能な最大の計画数は 10,000 です。参考情報については、「[apg\$1plan\$1mgmt.max\$1plans](#AuroraPostgreSQL.Optimize.Parameters.max_plans)」を参照してください。

このパラメータは、カスタム DB クラスターのパラメータグループまたはカスタム DB パラメータグループで設定できます。このパラメータの値を変更しても、再起動は必要ありません。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Parameters.html)

詳細については、「[Aurora PostgreSQL 実行計画のキャプチャ](AuroraPostgreSQL.Optimize.CapturePlans.md)」を参照してください。

## apg\$1plan\$1mgmt.plan\$1capture\$1threshold
<a name="AuroraPostgreSQL.Optimize.Parameters.plan_capture_threshold"></a>

クエリ実行計画の合計コストがしきい値を下回った場合に、計画が `apg_plan_mgmt.dba_plans` ビューにキャプチャされないようにしきい値を指定します。

このパラメータの値を変更しても、再起動は必要ありません。


| デフォルト | 許可される値 | 説明 | 
| --- | --- | --- | 
| 0 | 0 - 1.79769e\$1308 | プランをキャプチャするための `apg_plan_mgmt` クエリプランの合計実行コストのしきい値を設定します。  | 

詳細については、「[dba\$1plans ビューで Aurora PostgreSQL クエリ計画を検証する](AuroraPostgreSQL.Optimize.ViewPlans.md)」を参照してください。

## apg\$1plan\$1mgmt.explain\$1hashes
<a name="AuroraPostgreSQL.Optimize.Parameters.explain_hashes"></a>

`EXPLAIN [ANALYZE]` が出力の最後に `sql_hash` と `plan_hash` を表示するかどうかを指定します。このパラメータの値を変更しても、再起動は必要ありません。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Parameters.html)

## apg\$1plan\$1mgmt.log\$1plan\$1Enforcement\$1result
<a name="AuroraPostgreSQL.Optimize.Parameters.log_plan_enforcement_result"></a>

QPM 管理プランが適切に使用されているかどうかを確認するために結果を記録する必要があるかどうかを指定します。保存されているジェネリックプランを使用すると、ログファイルにレコードは書き込まれません。このパラメータの値を変更しても、再起動は必要ありません。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Parameters.html)

## apg\$1plan\$1mgmt.max\$1databases
<a name="AuroraPostgreSQL.Optimize.Parameters.max_databases"></a>

Aurora PostgreSQL DB クラスターのライターインスタンスで、クエリ計画管理を使用できるデータベースの最大数を指定します。デフォルトでは、最大 10 個のデータベースでクエリ計画管理を使用できます。インスタンスに 10 個を超えるデータベースがある場合は、この設定値を変更できます。特定のインスタンスにあるデータベースの数を確認するには、`psql` を使用してインスタンスに接続します。次に、psql メタコマンドの `\l` を使用して、データベースを一覧表示します。

このパラメータの値を変更した場合、設定を有効にするためにインスタンスを再起動する必要があります。


| デフォルト | 許可される値 | 説明 | 
| --- | --- | --- | 
| 10 | 10-2147483647 | インスタンスでクエリ計画管理を使用できるデータベースの最大数です。 | 

このパラメータは、カスタム DB クラスターのパラメータグループまたはカスタム DB パラメータグループで設定できます。

## apg\$1plan\$1mgmt.max\$1plans
<a name="AuroraPostgreSQL.Optimize.Parameters.max_plans"></a>

クエリプランマネージャが `apg_plan_mgmt.dba_plans` ビューで保持できる SQL ステートメントの最大数を設定します。Aurora PostgreSQL のすべてのバージョンで、このパラメータを `10000` 以上に設定することをお勧めします。

このパラメータは、カスタム DB クラスターのパラメータグループまたはカスタム DB パラメータグループで設定できます。このパラメータの値を変更した場合、設定を有効にするためにインスタンスを再起動する必要があります。


| デフォルト | 許可される値 | 説明 | 
| --- | --- | --- | 
| 10000 | 10-2147483647 | `apg_plan_mgmt.dba_plans` ビューに保存できる計画の最大数。 Aurora PostgreSQL バージョン 10 以前では、デフォルトは 1,000 です。  | 

詳細については、「[dba\$1plans ビューで Aurora PostgreSQL クエリ計画を検証する](AuroraPostgreSQL.Optimize.ViewPlans.md)」を参照してください。

## apg\$1plan\$1mgmt.plan\$1hash\$1version
<a name="AuroraPostgreSQL.Optimize.Parameters.plan_hash_version"></a>

plan\$1hash 計算が対象とするユースケースを指定します。`apg_plan_mgmt.plan_hash_version` の上位バージョンは、下位バージョンのすべての機能をカバーします。例えば、バージョン 3 はバージョン 2 でサポートされるユースケースをカバーします。

 このパラメータの値を変更した後は、`apg_plan_mgmt.validate_plans('update_plan_hash')` を呼び出す必要があります。apg\$1plan\$1mgmt がインストールされている各データベースの plan\$1hash 値とプランテーブルのエントリを更新します。詳細については、[計画の検証](AuroraPostgreSQL.Optimize.Deleting.md#AuroraPostgreSQL.Optimize.Maintenance.ValidatingPlans)を参照してください。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Parameters.html)

## apg\$1plan\$1mgmt.plan\$1retention\$1period
<a name="AuroraPostgreSQL.Optimize.Parameters.plan_retention_period"></a>

`apg_plan_mgmt.dba_plans` ビューで計画を保持する日数を指定し、それ以降は自動的に削除されます。デフォルトでは、計画は最後に使用されてから 32 日が経過すると削除されます (`apg_plan_mgmt.dba_plans` ビューの `last_used` 列)。この設定は、1 以上の任意の数に変更できます。

このパラメータの値を変更した場合、設定を有効にするためにインスタンスを再起動する必要があります。


| デフォルト | 許可される値 | 説明 | 
| --- | --- | --- | 
| 32 | 1-2147483647 | 計画が最後に使用された日付から、計画が自動的に削除されるまでの最大日数。 | 

詳細については、「[dba\$1plans ビューで Aurora PostgreSQL クエリ計画を検証する](AuroraPostgreSQL.Optimize.ViewPlans.md)」を参照してください。

## apg\$1plan\$1mgmt.unapproved\$1plan\$1execution\$1threshold
<a name="AuroraPostgreSQL.Optimize.Parameters.unapproved_plan_execution_threshold"></a>

オプティマイザによって未承認の計画を使用可能なコストのしきい値を指定します。デフォルトでは、しきい値は 0 で、オプティマイザは未承認の計画を実行しません。このパラメータを 100 などのごく低いコストのしきい値に設定すると、小さなプランに対するプラン適用のオーバーヘッドを回避できます。リアクティブスタイルのプラン管理では、このパラメータを 10000000 など、非常に大きな値に設定することもできます。これにより、オプティマイザはプラン適用のオーバーヘッドなしに、選択したすべてのプランを使用できます。ただし、不適切なプランが見つかった場合は、手動で「拒否」とマークして、次回使用されないようにすることができます。

このパラメータの値は、特定の計画を実行するためのコスト見積もりを表します。未承認計画が推定コストを下回る場合、オプティマイザはその計画を SQL ステートメントに使用します。`dba_plans` ビューで、キャプチャされた計画とそのステータス (承認済み、未承認) を確認できます。詳細については[dba\$1plans ビューで Aurora PostgreSQL クエリ計画を検証する](AuroraPostgreSQL.Optimize.ViewPlans.md)を参照してください。

このパラメータの値を変更しても、再起動は必要ありません。


| デフォルト | 許可される値 | 説明 | 
| --- | --- | --- | 
| 0 | 0-2147483647 | 未承認の計画が使用された場合、それ以下の見積もりの計画コスト | 

詳細については、「[Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)」を参照してください。

## apg\$1plan\$1mgmt.use\$1plan\$1baselines
<a name="AuroraPostgreSQL.Optimize.Parameters.use_plan_baselines"></a>

`apg_plan_mgmt.dba_plans` ビューでオプティマイザがキャプチャされ、保存された承認済み計画のいずれかを使用するように指定します。デフォルトでは、このパラメータはオフ (false) になっているため、オプティマイザが生成した最小コスト計画をそのまま使用します。このパラメータをオンにする (true に設定する) と、オプティマイザは計画ベースラインからステートメントのクエリ実行計画を選択するよう強制されます。詳細については、「[Aurora PostgreSQL 管理計画を使用する](AuroraPostgreSQL.Optimize.UsePlans.md)」を参照してください。このプロセスの詳細を示すイメージを検索するには、「[オプティマイザが実行する計画を選択する方法。](AuroraPostgreSQL.Optimize.UsePlans.md#AuroraPostgreSQL.Optimize.UsePlans.ChoosePlans)」を参照してください。

このパラメータは、カスタム DB クラスターのパラメータグループまたはカスタム DB パラメータグループで設定できます。このパラメータの値を変更しても、再起動は必要ありません。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Parameters.html)

必要に応じて、キャプチャしたさまざまな計画の応答時間を評価し、計画のステータスを変更できます。詳細については、「[Aurora PostgreSQL クエリ計画の改善](AuroraPostgreSQL.Optimize.Maintenance.md)」を参照してください。

## auto\$1explain.hashes
<a name="AuroraPostgreSQL.Optimize.Parameters.auto_explain.hashes"></a>

auto\$1explain の出力に sql\$1hash と plan\$1hash を表示するかどうかを指定します。このパラメータの値を変更しても、再起動は必要ありません。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Parameters.html)

# Aurora PostgreSQL クエリ計画管理の関数リファレンス
<a name="AuroraPostgreSQL.Optimize.Functions"></a>

`apg_plan_mgmt` エクステンションでは、以下の関数を使用できます。

**Topics**
+ [apg\$1plan\$1mgmt.copy\$1outline](#AuroraPostgreSQL.Optimize.Functions.copy_outline)
+ [apg\$1plan\$1mgmt.delete\$1plan](#AuroraPostgreSQL.Optimize.Functions.delete_plan)
+ [apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines)
+ [apg\$1plan\$1mgmt.get\$1explain\$1plan](#AuroraPostgreSQL.Optimize.Functions.get_explain_plan)
+ [apg\$1plan\$1mgmt.plan\$1last\$1used](#AuroraPostgreSQL.Optimize.Functions.plan_last_used)
+ [apg\$1plan\$1mgmt.reload](#AuroraPostgreSQL.Optimize.Functions.reload)
+ [apg\$1plan\$1mgmt.set\$1plan\$1enabled](#AuroraPostgreSQL.Optimize.Functions.set_plan_enabled)
+ [apg\$1plan\$1mgmt.set\$1plan\$1status](#AuroraPostgreSQL.Optimize.Functions.set_plan_status)
+ [apg\$1plan\$1mgmt.update\$1plans\$1last\$1used](#AuroraPostgreSQL.Optimize.Functions.update_plans_last_used)
+ [apg\$1plan\$1mgmt.validate\$1plans](#AuroraPostgreSQL.Optimize.Functions.validate_plans)

## apg\$1plan\$1mgmt.copy\$1outline
<a name="AuroraPostgreSQL.Optimize.Functions.copy_outline"></a>

特定の SQL プランハッシュとプランアウトラインをターゲットの SQL プランハッシュとアウトラインにコピーして、ターゲットのプランハッシュとアウトラインを上書きします。この関数は `apg_plan_mgmt` 2.3 以降のリリースで使用できます。

**構文**

```
apg_plan_mgmt.copy_outline(
    source_sql_hash,
    source_plan_hash,
    target_sql_hash,
    target_plan_hash,
    force_update_target_plan_hash
)
```

**戻り値**  
コピーが成功したときには、0 を返します。無効な入力に対して例外をレイズします。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| source\$1sql\$1hash  | ターゲットクエリにコピーする plan\$1hash に関連付けられた sql\$1hash ID。 | 
| source\$1plan\$1hash  | ターゲットクエリにコピーする plan\$1hash ID。 | 
| target\$1sql\$1hash | ソースプランハッシュとアウトラインで更新するクエリの sql\$1hash ID。 | 
| target\$1plan\$1hash | ソースプランハッシュとアウトラインで更新するクエリの plan\$1hash ID。 | 
| force\$1update\$1target\$1plan\$1hash | (オプション) ソースプランが target\$1sql\$1hash に対して再現可能ではない場合でも、クエリの target\$1plan\$1hash ID は更新されます。true に設定すると、この関数を使用して、リレーション名と列が一貫しているスキーマ間で計画をコピーできます。 | 

**使用に関する注意事項**

この関数を使用すると、ヒントを使用するプランハッシュとプランアウトラインを他の同様のステートメントにコピーできるため、ターゲットステートメントに出現するたびにインラインヒントステートメントを使用する必要がなくなります。更新されたターゲットクエリの結果、無効なプランになった場合、この関数はエラーをレイズして、試行された更新をロールバックします。

## apg\$1plan\$1mgmt.delete\$1plan
<a name="AuroraPostgreSQL.Optimize.Functions.delete_plan"></a>

管理計画を削除します。

**構文**

```
apg_plan_mgmt.delete_plan(
    sql_hash,
    plan_hash
)
```

**戻り値**  
削除が成功した場合は 0 を返し、削除が失敗した場合は -1 を返します。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| sql\$1hash  | 計画の管理 SQL ステートメントの sql\$1hash ID。 | 
| plan\$1hash | 管理計画の plan\$1hash ID。 | 

 

## apg\$1plan\$1mgmt.evolve\$1plan\$1baselines
<a name="AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines"></a>

既に承認された計画が速いか、またはクエリオプティマイザによって最小コスト計画として識別された計画が速いかを確認します。

**構文**

```
apg_plan_mgmt.evolve_plan_baselines(
    sql_hash, 
    plan_hash,
    min_speedup_factor,
    action
)
```

**戻り値**

最良の承認済み計画より遅かった計画の数。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| sql\$1hash | 計画の管理 SQL ステートメントの sql\$1hash ID。 | 
| plan\$1hash | 管理計画の plan\$1hash ID。同じ sql\$1hash ID 値を持つすべての計画を意味するために NULL を使用します。 | 
| min\$1speedup\$1factor |  *最小高速化係数*は、計画を承認するために最も速い承認済みの計画よりも速い回数です。または、計画がそれを拒否または無効にするよりも遅い回数を示します。 これは正の浮動値です。  | 
| action |  関数が実行するアクション。有効な値には次のようなものがあります。大文字と小文字は区別されません。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Functions.html)  | 

**使用に関する注意事項**

計画と実行時間が、最も速い承認済計画よりも設定可能な要素だけ速いかどうかに基づき指定された計画を承認済み、拒否、または無効に設定します。パフォーマンス基準を満たす計画を自動的に承認または拒否するには、アクションパラメータを `'approve'` または `'reject'` に設定します。あるいは、パフォーマンス実験を実行してレポートを作成するために '' (空の文字列) に設定することもできますが、何も実行されません。

最近実行されたプランに対して `apg_plan_mgmt.evolve_plan_baselines` 関数を無意味に再実行するのを防ぐことができます。そのためには、計画を最近作成された未承認の計画だけに制限します。あるいは、最近の `apg_plan_mgmt.evolve_plan_baselines` タイムスタンプを持つ承認済み計画で `last_verified` 関数を実行しないようにすることもできます。

ベースライン内の他の計画に対して、各計画の計画と実行時間を比較するためのパフォーマンス実験を実行します。場合によっては 1 つのステートメントに対して 1 つの計画しかなく、その計画が承認されます。このような場合は、計画の計画および実行時間、および計画を使用していない計画および実行時間を比較します。

各計画の増分利益 (またはデメリット) は、`apg_plan_mgmt.dba_plans` 列の `total_time_benefit_ms` ビューに記録されます。この値が正の値の場合、この計画をベースラインに含めることには、測定可能なパフォーマンス上の利点があります。

各候補計画の計画および実行時間を収集することに加えて、`last_verified` ビューの `apg_plan_mgmt.dba_plans` 列が `current_timestamp` で更新されます。`last_verified` タイムスタンプを使用して、最近パフォーマンスが検証された計画でこの関数を再度実行しないようにすることができます。

## apg\$1plan\$1mgmt.get\$1explain\$1plan
<a name="AuroraPostgreSQL.Optimize.Functions.get_explain_plan"></a>

指定された SQL ステートメントの `EXPLAIN` ステートメントのテキストを生成します。

**構文**

```
apg_plan_mgmt.get_explain_plan(
    sql_hash,
    plan_hash,
    [explainOptionList]
)
```

**戻り値**  
指定された SQL ステートメントの実行時統計を返します。簡単な `explainOptionList` プランを返すには `EXPLAIN` なしで使用します。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| sql\$1hash  | 計画の管理 SQL ステートメントの sql\$1hash ID。 | 
| plan\$1hash | 管理計画の plan\$1hash ID。 | 
| explainOptionList | カンマ区切りの説明オプション一覧。有効な値には、`'analyze'`、`'verbose'`、`'buffers'`、`'hashes'`、および `'format json'` があります。`explainOptionList` が NULL または空の文字列 ('') の場合、この関数は統計なしで `EXPLAIN` ステートメントを生成します。  | 

 

**使用に関する注意事項**

`explainOptionList` については、`EXPLAIN` ステートメントで使用するのと同じオプションのいずれかを使用できます。Aurora PostgreSQL オプティマイザは、`EXPLAIN` ステートメントに指定されたオプションのリストを連結します。

## apg\$1plan\$1mgmt.plan\$1last\$1used
<a name="AuroraPostgreSQL.Optimize.Functions.plan_last_used"></a>

指定された計画の `last_used` の日付を共有メモリから返します。

**注記**  
DB クラスター内のプライマリ DB インスタンスの共有メモリ値は、常に最新です。この値は `apg_plan_mgmt.dba_plans` ビューの `last_used` 列に周期的にしかフラッシュされません。

**構文**

```
apg_plan_mgmt.plan_last_used(
    sql_hash,
    plan_hash
)
```

**戻り値**  
`last_used` の日付を返します。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| sql\$1hash  | 計画の管理 SQL ステートメントの sql\$1hash ID。 | 
| plan\$1hash | 管理計画の plan\$1hash ID。 | 

 

## apg\$1plan\$1mgmt.reload
<a name="AuroraPostgreSQL.Optimize.Functions.reload"></a>

`apg_plan_mgmt.dba_plans` ビューから計画を共有メモリに再ロードします。

**構文**

```
apg_plan_mgmt.reload()
```

**戻り値**

なし。

**パラメータ**

なし。

**使用に関する注意事項**

次の状況では `reload` を呼び出してください。
+ 新しい計画がレプリカに伝播されるのを待たずに、読み取り専用レプリカの共有メモリをただちに更新するために使用する。
+ 管理計画をインポートした後に使用する。



## apg\$1plan\$1mgmt.set\$1plan\$1enabled
<a name="AuroraPostgreSQL.Optimize.Functions.set_plan_enabled"></a>

管理計画を有効または無効にします。

**構文**

```
apg_plan_mgmt.set_plan_enabled(
    sql_hash, 
    plan_hash, 
    [true | false]
)
```

**戻り値**

設定が成功した場合は 0 を返し、設定に失敗した場合は -1 を返します。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| sql\$1hash | 計画の管理 SQL ステートメントの sql\$1hash ID。 | 
| plan\$1hash | 管理計画の plan\$1hash ID。 | 
| enabled |  true または false のブール値。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Functions.html)  | 

 

## apg\$1plan\$1mgmt.set\$1plan\$1status
<a name="AuroraPostgreSQL.Optimize.Functions.set_plan_status"></a>

管理計画のステータスを `Approved`、`Unapproved`、`Rejected`、または `Preferred` に設定します。

**構文**

```
apg_plan_mgmt.set_plan_status(
    sql_hash, 
    plan_hash, 
    status
)
```

**戻り値**

設定が成功した場合は 0 を返し、設定に失敗した場合は -1 を返します。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| sql\$1hash | 計画の管理 SQL ステートメントの sql\$1hash ID。 | 
| plan\$1hash | 管理計画の plan\$1hash ID。 | 
| status |  次のいずれかの値を持つ文字列: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Functions.html) 大文字と小文字の使い分けは重要ではありませんが、ステータス値は `apg_plan_mgmt.dba_plans` ビューで先頭文字が大文字に設定されます。これらの値についての詳細は `status` の [Aurora PostgreSQL 互換エディションの apg\$1plan\$1mgmt.dba\$1plans ビューのリファレンス](AuroraPostgreSQL.Optimize.dba_plans_view_Reference.md) を参照してください。  | 

 

## apg\$1plan\$1mgmt.update\$1plans\$1last\$1used
<a name="AuroraPostgreSQL.Optimize.Functions.update_plans_last_used"></a>

プランテーブルを共有メモリに格納されている `last_used` の日付に即座に更新する。

**構文**

```
apg_plan_mgmt.update_plans_last_used()
```

**戻り値**

なし。

**パラメータ**

なし。

**使用に関する注意事項**

`update_plans_last_used` を呼び出して `dba_plans.last_used` 列に対するクエリが最新の情報を使用しているか確認します。`last_used` の日付が即座に更新されない場合、バックグラウンドプロセスはデフォルトで毎時間に一回、プランテーブルを `last_used` 日付で更新します。

例えば、特定の `sql_hash` ステートメントの実行速度が遅くなった場合、パフォーマンスリグレッションスタート以降、そのステートメントにどのプランが実行されたかを判断できます。これを行うには、まず共有メモリ内のデータをディスクにフラッシュして `last_used` の日付を最新のものにし、その後パフォーマンスリグレッションのある `sql_hash` ステートメントのすべてのプランにクエリを実行します。クエリでは、`last_used` の日付がパフォーマンスリグレッションがスタートされた日付と一緒か、それ以降になるようにしてください。クエリは、パフォーマンスリグレッションの原因の可能性があるプランまたは一連のプランを識別します。`verbose, hashes` に設定された `explainOptionList` で `apg_plan_mgmt.get_explain_plan` を使用することができます。また `apg_plan_mgmt.evolve_plan_baselines` を使用して、より優れたパフォーマンスを得れるかもしれないプランや代行プランを分析することができます。

`update_plans_last_used` 関数は、DB クラスターのプライマリ DB インスタンスにのみ影響します。

## apg\$1plan\$1mgmt.validate\$1plans
<a name="AuroraPostgreSQL.Optimize.Functions.validate_plans"></a>

オプティマイザがまだ計画を再作成できることを確認してください。オプティマイザは `Approved` 計画、`Unapproved` 計画、および `Preferred` 計画について、計画が有効か無効かを検証します。`Rejected` 計画は検証されません。オプションで、`apg_plan_mgmt.validate_plans` 関数を使用して無効な計画を削除または無効にすることができます。

**構文**

```
apg_plan_mgmt.validate_plans(
    sql_hash, 
    plan_hash, 
    action)
            
apg_plan_mgmt.validate_plans(
    action)
```

**戻り値**

無効な計画の数です。

**パラメータ**


****  

| Parameter | 説明 | 
| --- | --- | 
| sql\$1hash | 計画の管理 SQL ステートメントの sql\$1hash ID。 | 
| plan\$1hash | 管理計画の plan\$1hash ID。同じ sql\$1hash ID 値のすべての計画を意味するために NULL を使用します。 | 
| action |  関数が無効な計画に実行するアクションです。有効な文字列値は次のとおりです。大文字と小文字は区別されません。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Functions.html) 他の値は空の文字列のように扱われます。  | 

**使用に関する注意事項**

`validate_plans(action)` ビュー全体で、すべての管理ステートメントのすべての計画を検証するには、`apg_plan_mgmt.dba_plans` 形式を使用してください。

`validate_plans(sql_hash, plan_hash, action)` で指定された管理ステートメントについて、`plan_hash` の形式を使用して、`sql_hash` で指定された管理計画を検証します。

`validate_plans(sql_hash, NULL, action)` で指定した管理ステートメントのすべての管理計画を検証するには、`sql_hash` の形式を使用してください。

# Aurora PostgreSQL 互換エディションの apg\$1plan\$1mgmt.dba\$1plans ビューのリファレンス
<a name="AuroraPostgreSQL.Optimize.dba_plans_view_Reference"></a>

`apg_plan_mgmt.dba_plans` ビューの計画情報の列には以下のものが含まれます。


| dba\$1plans 列 | 説明 | 
| --- | --- | 
| cardinality\$1error |  推定濃度と実際の濃度の間の誤差の程度。*濃度*とは、計画により処理されるテーブルの行数です。濃度誤差が大きい場合、計画が最適ではない可能性が高くなります。この列は [apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines) 関数によって入力されます。  | 
| compatibility\$1level |  このパラメータは、クエリプランが最後に検証された日時を示します。Aurora PostgreSQL バージョン 12.19、13.15、14.12、15.7、16.3 以降では、Aurora バージョン番号が表示されます。それより前のバージョンでは、機能固有のバージョン番号が表示されます。  このパラメータ値はデフォルト設定のままにしておきます。Aurora PostgreSQL は、この値を自動的に設定および更新します。   | 
| created\$1by | 計画を作成した認証済みユーザー (session\$1user)。 | 
| enabled |  計画が有効か無効かを示すインジケータ。すべての計画はデフォルトで有効になっています。計画を無効にして、オプティマイザが計画を使用しないようにすることができます。この値を変更するには、[apg\$1plan\$1mgmt.set\$1plan\$1enabled](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.set_plan_enabled) 関数を使用します。  | 
| environment\$1variables |  計画の取得時点でオプティマイザにより上書きされた、PostgreSQL Grand Unified Configuration (GUC) のパラメータおよび値。  | 
| estimated\$1startup\$1cost | オプティマイザがテーブルの行を配信する前の、推定オプティマイザ設定コスト。 | 
| estimated\$1total\$1cost | 最終テーブル行を配信するための推定オプティマイザコスト。 | 
| execution\$1time\$1benefit\$1ms | 計画を有効にすることで速くなる実行時間。この列は [apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines) 関数によって入力されます。 | 
| execution\$1time\$1ms | 計画が実行される推定時間 (ミリ秒)。この列は [apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines) 関数によって入力されます。 | 
| has\$1side\$1effects | SQL ステートメントがデータ操作言語 (DML) ステートメント、または VOLATILE 関数を含む SELECT ステートメントであることを示す値。 | 
| last\$1used | この値は、計画の実行時、または計画がクエリオプティマイザの最小コスト計画であるときに、現在の日付に更新されます。この値は共有メモリに保存され、定期的にディスクにフラッシュされます。最新の値を取得するには、apg\$1plan\$1mgmt.plan\$1last\$1used(sql\$1hash, plan\$1hash) の値を読み取る代わりに関数 last\$1used を呼び出して、共有メモリから日付を読み取ります。詳細については、[apg\$1plan\$1mgmt.plan\$1retention\$1period](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.plan_retention_period) パラメータを参照してください。 | 
| last\$1validated | 計画が [apg\$1plan\$1mgmt.validate\$1plans](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.validate_plans) 関数または [apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines) 関数のいずれかにより再作成可能であることが検証された最新の日時。 | 
| last\$1verified | 計画が、[apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines) 関数で指定されたパラメータに対して最もパフォーマンスの高い計画であることが検証された最新の日時。 | 
| origin |  [apg\$1plan\$1mgmt.capture\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.capture_plan_baselines) パラメータを使用して計画が取得された方法。有効な値には次のようなものがあります。 `M` - 計画は、手動計画取り込みで取得されています。 `A` - 計画は、自動計画取り込みで取得されています。  | 
| param\$1list |  ステートメントに渡されたパラメータ値 (これが準備済みステートメントである場合)。  | 
| plan\$1created | 計画が作成された日時。 | 
| plan\$1hash | 計画の識別子。plan\$1hash と sql\$1hash の組み合わせにより、特定の計画を一意に識別できます。 | 
| plan\$1outline | 実際の実行計画を再作成するために使用された、データベースに依存しない計画の表現。ツリーの演算子は、EXPLAIN 出力に表示される演算子に対応しています。 | 
| planning\$1time\$1ms |  プランナーを実際に実行する時間 (ミリ秒)。この列は [apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines) 関数によって入力されます。  | 
| queryId | pg\$1stat\$1statements エクステンションによって計算されたステートメントのハッシュ。これはオブジェクト識別子 (OID) に依存しています。安定識別子や非データベース依存の識別子ではありません。クエリプランをキャプチャするとき、compute\$1query\$1id が off の場合、値は 0  になります。 | 
| sql\$1hash | リテラルを削除して正規化した、SQL ステートメントのテキストのハッシュ値。 | 
| sql\$1text | SQL ステートメントのフルテキスト。 | 
| status |  オプティマイザによる計画の使用方法を決定する、計画のステータス。有効な値には次のようなものがあります。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.dba_plans_view_Reference.html)  | 
| stmt\$1name | PREPARE ステートメント内の SQL ステートメントの名前。名前のない準備済みステートメントの場合、この値は空の文字列になります。名前のないステートメントの場合、この値は NULL になります。 | 
| total\$1time\$1benefit\$1ms |  この計画を有効にすることで速くなる実行時間の合計。この値には、計画時間と実行時間の両方が考慮されます。 この値が負の場合、この計画を有効にすることは推奨されません。この列は [apg\$1plan\$1mgmt.evolve\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Functions.md#AuroraPostgreSQL.Optimize.Functions.evolve_plan_baselines) 関数によって入力されます。  | 

# クエリ計画管理の高度な機能
<a name="AuroraPostgreSQL.QPM.Advanced"></a>

Aurora PostgreSQL クエリプラン管理 (QPM) の高度な機能に関する情報は、以下に記載されています。

**Topics**
+ [レプリカでの Aurora PostgreSQL 実行プランのキャプチャ](AuroraPostgreSQL.QPM.Plancapturereplicas.md)
+ [テーブルパーティションのサポート](AuroraPostgreSQL.QPM.Partitiontable.md)

# レプリカでの Aurora PostgreSQL 実行プランのキャプチャ
<a name="AuroraPostgreSQL.QPM.Plancapturereplicas"></a>

QPM (クエリプラン管理) を使用すると、Aurora Replicas によって生成されたクエリプランをキャプチャし、Aurora DB クラスターのプライマリ DB インスタンスに保存できます。すべての Aurora Replicas からクエリプランを収集し、プライマリインスタンスの中央永続テーブルで最適なプランのセットを管理できます。その後、必要に応じてこれらのプランを他のレプリカに適用できます。これにより、DB クラスターやエンジンバージョン全体にわたって実行プランの安定性を維持し、クエリのパフォーマンスを向上させることができます。

**Topics**
+ [前提条件](#AuroraPostgreSQL.QPM.Plancapturereplicas.Prereq)
+ [Aurora Replicas のプランキャプチャの管理](#AuroraPostgreSQL.QPM.Plancapturereplicas.managing)
+ [トラブルシューティング](#AuroraPostgreSQL.QPM.Plancapturereplicas.Troubleshooting)

## 前提条件
<a name="AuroraPostgreSQL.QPM.Plancapturereplicas.Prereq"></a>

**Aurora レプリカで `capture_plan_baselines parameter` を有効にする** - Aurora Replicas でプランをキャプチャするには、`capture_plan_baselines` パラメーターを自動または手動に設定します。詳細については、「[apg\$1plan\$1mgmt.capture\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.capture_plan_baselines)」を参照してください。

**postgres\$1fdw 拡張機能をインストールする** - Aurora Replicas でプランをキャプチャするには、`postgres_fdw` 外部データラッパー拡張機能をインストールする必要があります。拡張機能をインストールするには、各データベースで次のコマンドを実行します。

```
postgres=> CREATE EXTENSION IF NOT EXISTS postgres_fdw;
```

## Aurora Replicas のプランキャプチャの管理
<a name="AuroraPostgreSQL.QPM.Plancapturereplicas.managing"></a>

**Aurora Replicas のプランキャプチャをオンにする**  
Aurora Replicas でプランキャプチャを作成または削除するには、`rds_superuser` 権限が必要です。ユーザーのロールとアクセス許可の詳細については、「[PostgreSQL のロールとアクセス許可の理解](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Roles.html)」を参照してください。

プランをキャプチャするには、以下に示すように、ライター DB インスタンスで関数 apg\$1plan\$1mgmt.create\$1replica\$1plan\$1capture を呼び出します。

```
postgres=> CALL apg_plan_mgmt.create_replica_plan_capture('endpoint', 'password');
```
+ エンドポイント - Aurora Global Database ライターエンドポイントまたは cluster\$1endpoint は、Aurora Replicas でのプランキャプチャに対してフェイルオーバーのサポートを提供します。

  Aurora Global Database ライターエンドポイントの詳細については、「[Amazon Aurora Global Database のエンドポイントの表示](aurora-global-database-connecting.md#viewing-endpoints)」を参照してください。

  クラスターエンドポイントの詳細については、「[Amazon Aurora のクラスターエンドポイント](Aurora.Endpoints.Cluster.md)」を参照してください。
+ パスワード - セキュリティを強化するためにパスワードを作成する際は、以下のガイドラインに従うことをお勧めします。
  + 少なくとも 8 文字を含める必要があります。
  + 少なくとも大文字 1 つ、小文字 1 つ、および 数字 1 つを含める必要があります。
  + 少なくとも 1 つの特殊文字 (`?`、`!`、`#`、`<`、`>`、`*`、など) を含める必要です。

**注記**  
エンドポイント、パスワード、またはポート番号を変更した場合は、エンドポイントとパスワードを使用して `apg_plan_mgmt.create_replica_plan_capture()` を再実行し、プランキャプチャを再初期化する必要があります。そうでない場合、Aurora Replicas からのプランのキャプチャは失敗します。

**Aurora Replicas のプランキャプチャをオフにする**  
Aurora Replicas の `capture_plan_baselines` パラメータをオフにするには、パラメータグループの値を `off` に設定します。

**Aurora Replicas のプランキャプチャを削除する**  
Aurora Replicas のプランキャプチャは完全に削除できますが、削除する前に確認してください。プランキャプチャを削除するには、以下のように `apg_plan_mgmt.remove_replica_plan_capture` を呼び出します。

```
postgres=> CALL apg_plan_mgmt.remove_replica_plan_capture();
```

エンドポイントとパスワードを使用して Aurora Replicas のプランキャプチャをオンにするには、apg\$1plan\$1mgmt.create\$1replica\$1plan\$1capture() を再度呼び出す必要があります。

## トラブルシューティング
<a name="AuroraPostgreSQL.QPM.Plancapturereplicas.Troubleshooting"></a>

以下に、プランが想定どおりに Aurora Replicas にキャプチャされない場合のトラブルシューティングのヒントと回避策を示します。
+ **パラメータ設定** - プランキャプチャを有効にするために `capture_plan_baselines` パラメータが適切な値に設定されているかどうかを確認してください。
+ **`postgres_fdw` 拡張機能がインストールされている** - 次のクエリを使用して `postgres_fdw` がインストールされているかどうかを確認してください。

  ```
  postgres=> SELECT * FROM pg_extension WHERE extname = 'postgres_fdw'
  ```
+ **create\$1replica\$1plan\$1capture() が呼び出されている** - 以下のコマンドを使用して、ユーザーマッピングが終了しているかどうかを確認します。それ以外の場合は、`create_replica_plan_capture()` を呼び出して機能を初期化します。

  ```
  postgres=> SELECT * FROM pg_foreign_server WHERE srvname = 'apg_plan_mgmt_writer_foreign_server';
  ```
+ **エンドポイントとポート番号** - エンドポイントとポート番号が適切かどうかを確認してください。これらの値が間違っていても、エラーメッセージは表示されません。

  次のコマンドを使用して、エンドポイントが create() で使用されているかどうかを確認し、そのエンドポイントがどのデータベースにあるかを確認します。

  ```
  postgres=> SELECT srvoptions FROM pg_foreign_server WHERE srvname = 'apg_plan_mgmt_writer_foreign_server';
  ```
+ **reload()** - 削除機能を有効にするには、Aurora Replicas で apg\$1plan\$1mgmt.delete\$1plan() を呼び出した後に apg\$1plan\$1mgmt.reload() を呼び出す必要があります。これにより、変更が正常に実装されたことが保証されます。
+ **パスワード** - 記載されているガイドラインに従って create\$1replica\$1plan\$1capture() にパスワードを入力する必要があります。入力しないと、エラーメッセージが表示されます。詳細については、「[Aurora Replicas のプランキャプチャの管理](#AuroraPostgreSQL.QPM.Plancapturereplicas.managing)」を参照してください。要件に合った別のパスワードを使用してください。
+ **クロスリージョン接続** - Aurora Replicas でのプランキャプチャは Aurora グローバルデータベースでもサポートされており、ライターインスタンスと Aurora Replicas は異なるリージョンに配置できます。Aurora Global Database ライターエンドポイントを使用して、フェイルオーバーイベントまたはスイッチオーバーイベント後に接続を維持してください。Aurora Global Database エンドポイントの詳細については、「[Amazon Aurora Global Database のエンドポイントの表示](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-global-database-connecting.html#viewing-endpoints)」を参照してください。ライターインスタンスとクロスリージョンレプリカは VPC ピアリングを使用して通信できる必要があります。詳細については、「[VPC ピアリング接続](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html)」を参照してください。クロスリージョンフェイルオーバーが発生した場合、エンドポイントを新しいプライマリ DB クラスターエンドポイントに再設定する必要があります。
**注記**  
Aurora Global Database ライターエンドポイントの代わりにクラスターエンドポイントを使用する場合は、グローバルフェイルオーバーまたはスイッチオーバーオペレーションを実行した後にクラスターエンドポイントを更新する必要があります。

# テーブルパーティションのサポート
<a name="AuroraPostgreSQL.QPM.Partitiontable"></a>

Aurora PostgreSQL クエリプラン管理 (QPM) は、以下のバージョンで宣言的テーブルパーティショニングをサポートしています。
+ 15.3 以降の 15 バージョン
+ 14.8 以降の 14 バージョン
+ 13.11 以降の 13 バージョン

詳細については、「[テーブルのパーティション](https://www.postgresql.org/docs/current/ddl-partitioning.html)」を参照してください。

**Topics**
+ [テーブルパーティションの設定](#AuroraPostgreSQL.QPM.Partitiontable.setup)
+ [テーブルパーティションのプランのキャプチャ](#AuroraPostgreSQL.QPM.Partitiontable.capture)
+ [テーブルパーティションプランの実施](#AuroraPostgreSQL.QPM.Partitiontable.enforcement)
+ [命名規則](#AuroraPostgreSQL.QPM.Partitiontable.naming.convention)

## テーブルパーティションの設定
<a name="AuroraPostgreSQL.QPM.Partitiontable.setup"></a>

 Aurora PostgreSQL QPM でテーブルパーティションをセットアップするには、以下の手順を実行してください。

1. DB クラスターパラメータグループで `apg_plan_mgmt.plan_hash_version` を 3 以上に設定します。

1. クエリプラン管理を使用し、`apg_plan_mgmt.dba_plans` ビューにエントリがあるデータベースに移動します。

1. `apg_plan_mgmt.validate_plans('update_plan_hash')` を呼び出して、プランテーブルの `plan_hash` 値を更新します。

1. クエリプラン管理が有効になっていて、`apg_plan_mgmt.dba_plans` ビューにエントリがあるすべてのデータベースについて、手順 2～3 を繰り返します。

これらのパラメータの詳細については、「[Aurora PostgreSQL クエリ計画管理のパラメータリファレンス](AuroraPostgreSQL.Optimize.Parameters.md)」を参照してください。

## テーブルパーティションのプランのキャプチャ
<a name="AuroraPostgreSQL.QPM.Partitiontable.capture"></a>

QPM では、さまざまなプランが `plan_hash` 値によって区別されます。`plan_hash` がどのように変化するかを理解するには、まず、同様の種類のプランを理解する必要があります。

Append ノードレベルで蓄積されるアクセス方法、数字を取り除いたインデックス名、および数字を取り除いたパーティション名の組み合わせが同じであれば、プランは同じと見なされます。プランでアクセスされる特定のパーティションは重要ではありません。次の例では、テーブル `tbl_a` は 4 つのパーティションで作成されます。

```
postgres=>create table tbl_a(i int, j int, k int, l int, m int) partition by range(i);
CREATE TABLE
postgres=>create table tbl_a1 partition of tbl_a for values from (0) to (1000);
CREATE TABLE
postgres=>create table tbl_a2 partition of tbl_a for values from (1001) to (2000);
CREATE TABLE
postgres=>create table tbl_a3 partition of tbl_a for values from (2001) to (3000);
CREATE TABLE
postgres=>create table tbl_a4 partition of tbl_a for values from (3001) to (4000);
CREATE TABLE
postgres=>create index t_i on tbl_a using btree (i);
CREATE INDEX
postgres=>create index t_j on tbl_a using btree (j);
CREATE INDEX
postgres=>create index t_k on tbl_a using btree (k);
CREATE INDEX
```

クエリが検索するパーティションの数に関係なく、単一のスキャン方法を使用して `tbl_a` をスキャンするため、次のプランは同じと見なされます。

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 999 and j < 9910 and k > 50;
            
                        QUERY PLAN
-------------------------------------------------------------------
Seq Scan on tbl_a1 tbl_a
    Filter: ((i >= 990) AND (i <= 999) AND (j < 9910) AND (k > 50))
SQL Hash: 1553185667, Plan Hash: -694232056
(3 rows)
```

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;
            
                        QUERY PLAN
-------------------------------------------------------------------
Append
    ->  Seq Scan on tbl_a1 tbl_a_1
            Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50))
    ->  Seq Scan on tbl_a2 tbl_a_2
            Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50))
    SQL Hash: 1553185667, Plan Hash: -694232056
    (6 rows)
```

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;
            
                QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Seq Scan on tbl_a1 tbl_a_1
         Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a3 tbl_a_3
         Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
 SQL Hash: 1553185667, Plan Hash: -694232056
(8 rows)
```

次の 3 つのプランも同じとみなされます。親レベルで、アクセス方法、数字を取り除いたインデックス名、および数字を取り除いたパーティション名は、`SeqScan tbl_a`、`IndexScan (i_idx) tbl_a` であるためです。

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;
            
                                QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Seq Scan on tbl_a1 tbl_a_1
         Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50))
   ->  Index Scan using tbl_a2_i_idx on tbl_a2 tbl_a_2
         Index Cond: ((i >= 990) AND (i <= 1100))
         Filter: ((j < 9910) AND (k > 50))
 SQL Hash: 1553185667, Plan Hash: -993736942
(7 rows)
```

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;
            
                                QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1
         Index Cond: ((i >= 990) AND (i <= 2100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
   ->  Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3
         Index Cond: ((i >= 990) AND (i <= 2100))
         Filter: ((j < 9910) AND (k > 50))
 SQL Hash: 1553185667, Plan Hash: -993736942
(10 rows)
```

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 3100 and j < 9910 and k > 50;
            
                                QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Seq Scan on tbl_a1 tbl_a_1
         Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a3 tbl_a_3
         Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50))
   ->  Index Scan using tbl_a4_i_idx on tbl_a4 tbl_a_4
         Index Cond: ((i >= 990) AND (i <= 3100))
         Filter: ((j < 9910) AND (k > 50))
 SQL Hash: 1553185667, Plan Hash: -993736942
(11 rows)
```

子パーティション内の出現順序や出現回数が異なっていても、アクセス方法、数字を取り除いたインデックス名、および数字を取り除いたパーティション名は、上記の各プランの親レベルで同じです。

ただし、次の条件のいずれかが満たされる場合、プランは異なると見なされます。
+ プランで追加のアクセス方法が使用される。

  ```
  postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;
                      
                                  QUERY PLAN
  --------------------------------------------------------------------------
   Append
     ->  Seq Scan on tbl_a1 tbl_a_1
           Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
     ->  Seq Scan on tbl_a2 tbl_a_2
           Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
     ->  Bitmap Heap Scan on tbl_a3 tbl_a_3
           Recheck Cond: ((i >= 990) AND (i <= 2100))
           Filter: ((j < 9910) AND (k > 50))
           ->  Bitmap Index Scan on tbl_a3_i_idx
                 Index Cond: ((i >= 990) AND (i <= 2100))
   SQL Hash: 1553185667, Plan Hash: 1134525070
  (11 rows)
  ```
+ プラン内のどのアクセス方法もそれ以上使用されない。

  ```
  postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;
                      
                                 QUERY PLAN
  --------------------------------------------------------------------------
   Append
     ->  Seq Scan on tbl_a1 tbl_a_1
           Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50))
     ->  Seq Scan on tbl_a2 tbl_a_2
           Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50))
   SQL Hash: 1553185667, Plan Hash: -694232056
  (6 rows)
  ```
+ インデックスメソッドに関連付けられたインデックスが変更された。

  ```
  postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;
                      
                               QUERY PLAN
  --------------------------------------------------------------------------
   Append
     ->  Seq Scan on tbl_a1 tbl_a_1
           Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50))
     ->  Index Scan using tbl_a2_j_idx on tbl_a2 tbl_a_2
           Index Cond: (j < 9910)
           Filter: ((i >= 990) AND (i <= 1100) AND (k > 50))
   SQL Hash: 1553185667, Plan Hash: -993343726
  (7 rows)
  ```

## テーブルパーティションプランの実施
<a name="AuroraPostgreSQL.QPM.Partitiontable.enforcement"></a>

パーティションテーブルについて承認されたプランは、位置対応で実施されます。プランはパーティションに固有ではなく、元のクエリで参照されているプラン以外のパーティションにも適用できます。プランには、最初に承認されたアウトラインとは異なる数のパーティションにアクセスするクエリを強制する機能もあります。

例えば、承認されたアウトラインが次のプランに関するものであるとします。

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;
            
                                QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1
         Index Cond: ((i >= 990) AND (i <= 2100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
   ->  Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3
         Index Cond: ((i >= 990) AND (i <= 2100))
         Filter: ((j < 9910) AND (k > 50))   
 SQL Hash: 1553185667, Plan Hash: -993736942
(10 rows)
```

この場合、このプランは、2、4、またはそれ以上のパーティションを参照する SQL クエリにも適用できます。これらのシナリオで、2 パーティションと 4 パーティションのアクセスについて考えられるプランは以下のとおりです。

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1100 and j < 9910 and k > 50;
            
                                QUERY PLAN
----------------------------------------------------------------------------------
 Append
   ->  Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1
         Index Cond: ((i >= 990) AND (i <= 1100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 1100) AND (j < 9910) AND (k > 50))
 Note: An Approved plan was used instead of the minimum cost plan. 
 SQL Hash: 1553185667, Plan Hash: -993736942, Minimum Cost Plan Hash: -1873216041
(8 rows)
```

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 3100 and j < 9910 and k > 50;
            
                                QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1
         Index Cond: ((i >= 990) AND (i <= 3100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50))
   ->  Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3
         Index Cond: ((i >= 990) AND (i <= 3100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a4 tbl_a_4
         Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50))
 Note: An Approved plan was used instead of the minimum cost plan.
 SQL Hash: 1553185667, Plan Hash: -993736942, Minimum Cost Plan Hash: -1873216041 
(12 rows)
```

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 3100 and j < 9910 and k > 50;
            
                                QUERY PLAN
----------------------------------------------------------------------------------
 Append
   ->  Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1
         Index Cond: ((i >= 990) AND (i <= 3100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 3100) AND (j < 9910) AND (k > 50))
   ->  Index Scan using tbl_a3_i_idx on tbl_a3 tbl_a_3
         Index Cond: ((i >= 990) AND (i <= 3100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Index Scan using tbl_a4_i_idx on tbl_a4 tbl_a_4
         Index Cond: ((i >= 990) AND (i <= 3100))
         Filter: ((j < 9910) AND (k > 50))
 Note: An Approved plan was used instead of the minimum cost plan.
 SQL Hash: 1553185667, Plan Hash: -993736942, Minimum Cost Plan Hash: -1873216041
(14 rows)
```

パーティションごとにアクセス方法が異なる別の承認済みプランを考えてみましょう。

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 2100 and j < 9910 and k > 50;
            
                                QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1
         Index Cond: ((i >= 990) AND (i <= 2100))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 2100) AND (j < 9910) AND (k > 50))
   ->  Bitmap Heap Scan on tbl_a3 tbl_a_3
         Recheck Cond: ((i >= 990) AND (i <= 2100))
         Filter: ((j < 9910) AND (k > 50))
         ->  Bitmap Index Scan on tbl_a3_i_idx
               Index Cond: ((i >= 990) AND (i <= 2100))
 SQL Hash: 1553185667, Plan Hash: 2032136998
(12 rows)
```

この場合、2 つのパーティションからデータを読み込むプランは適用されません。承認されたプランの（アクセス方法、インデックス名）の組み合わせがすべて使用可能でない限り、プランを実施することはできません。例えば、以下のプランはプランのハッシュが異なり、承認されたプランはこのような場合には適用できません。

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1900 and j < 9910 and k > 50;
            
                              QUERY PLAN
-------------------------------------------------------------------------
 Append
   ->  Bitmap Heap Scan on tbl_a1 tbl_a_1
         Recheck Cond: ((i >= 990) AND (i <= 1900))
         Filter: ((j < 9910) AND (k > 50))
         ->  Bitmap Index Scan on tbl_a1_i_idx
               Index Cond: ((i >= 990) AND (i <= 1900))
   ->  Bitmap Heap Scan on tbl_a2 tbl_a_2
         Recheck Cond: ((i >= 990) AND (i <= 1900))
         Filter: ((j < 9910) AND (k > 50))
         ->  Bitmap Index Scan on tbl_a2_i_idx
               Index Cond: ((i >= 990) AND (i <= 1900))
  Note: This is not an Approved plan.  No usable Approved plan was found.
  SQL Hash: 1553185667, Plan Hash: -568647260
(13 rows)
```

```
postgres=>explain (hashes true, costs false) select j, k from tbl_a where i between 990 and 1900 and j < 9910 and k > 50;
            
                              QUERY PLAN
--------------------------------------------------------------------------
 Append
   ->  Index Scan using tbl_a1_i_idx on tbl_a1 tbl_a_1
         Index Cond: ((i >= 990) AND (i <= 1900))
         Filter: ((j < 9910) AND (k > 50))
   ->  Seq Scan on tbl_a2 tbl_a_2
         Filter: ((i >= 990) AND (i <= 1900) AND (j < 9910) AND (k > 50))
 Note: This is not an Approved plan.  No usable Approved plan was found.
 SQL Hash: 1553185667, Plan Hash: -496793743
(8 rows)
```

## 命名規則
<a name="AuroraPostgreSQL.QPM.Partitiontable.naming.convention"></a>

QPM が宣言的パーティションテーブルでプランを適用するには、親テーブル、テーブルパーティション、インデックスに固有の命名規則に従う必要があります。
+ **親テーブル名** - これらの名前は、数字だけでなく、アルファベットまたは特殊文字が異なっていなければなりません。例えば、tA、tB、tC は個別の親テーブルには使用できる名前ですが、t1、t2、t3 はそうではありません。
+ **各パーティションテーブル名** - 同じ親を持つパーティション名は、数字のみが異なっている必要があります。例えば、tA に指定できるパーティション名は tA1、tA2、t1a、t2A、または複数桁の場合もあります。

  その他の違い (文字、特殊文字) があっても、プランの適用は保証されません。
+ **インデックス名** – パーティションテーブル階層で、すべてのインデックスに一意の名前があることを確認します。つまり、名前の数値以外の部分は異なっている必要があります。例えば、`tA_col1_idx1` という名前のインデックスを持つ `tA` という名前のパーティションテーブルがある場合、`tA_col1_idx2` という名前の別のインデックスを使用することはできません。ただし、`tA_a_col1_idx2` というインデックスは、数値以外の部分が一意であるため使用できます。このルールは、親テーブルと個々のパーティションテーブルの両方で作成されたインデックスに適用されます。

 上記の命名規則に従わないと、承認されたプランの実施に失敗する可能性があります。次の例は、このような実施が失敗したことを示しています。

```
postgres=>create table t1(i int, j int, k int, l int, m int) partition by range(i);
CREATE TABLE
postgres=>create table t1a partition of t1 for values from (0) to (1000);
CREATE TABLE
postgres=>create table t1b partition of t1 for values from (1001) to (2000);
CREATE TABLE
postgres=>SET apg_plan_mgmt.capture_plan_baselines TO 'manual';
SET
postgres=>explain (hashes true, costs false) select count(*) from t1 where i > 0;

                            QUERY PLAN
--------------------------------------------------------------------------
 Aggregate
   ->  Append
         ->  Seq Scan on t1a t1_1
               Filter: (i > 0)
         ->  Seq Scan on t1b t1_2
               Filter: (i > 0)
 SQL Hash: -1720232281, Plan Hash: -1010664377
(7 rows)
```

```
postgres=>SET apg_plan_mgmt.use_plan_baselines TO 'on';
SET
postgres=>explain (hashes true, costs false) select count(*) from t1 where i > 1000;

                            QUERY PLAN
-------------------------------------------------------------------------
 Aggregate
   ->  Seq Scan on t1b t1
         Filter: (i > 1000)
 Note: This is not an Approved plan. No usable Approved plan was found.
 SQL Hash: -1720232281, Plan Hash: 335531806
(5 rows)
```

2 つのプランは同じように見えますが、子テーブルの名前によって `Plan Hash` 値は異なります。数値のみでなくアルファベット文字で名前が異なるテーブルでは、プランの実施が失敗します。