

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 管理 Aurora PostgreSQL 的查詢執行計劃
<a name="AuroraPostgreSQL.Optimize"></a>

Aurora PostgreSQL 查詢計劃管理是選用功能，您可以搭配 Amazon Aurora PostgreSQL 相容版本資料庫叢集使用。此功能封裝成您可以將其安裝在 Aurora PostgreSQL 資料庫叢集中的 `apg_plan_mgmt` 延伸模組。查詢計畫管理可讓您管理最佳化工具針對 SQL 應用程式產生的查詢執行計劃。`apg_plan_mgmt` AWS 延伸項目是以 PostgreSQL 資料庫引擎的原生查詢處理功能為基礎。

接下來，您可以尋找 Aurora PostgreSQL 查詢計劃管理功能、如何進行設定，以及如何將其與 Aurora PostgreSQL 資料庫叢集搭配使用的相關資訊。在開始之前，建議您檢閱 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 文件中的 [Dynamic 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 查詢計劃管理支援所有 PostgreSQL 語言功能，包括分割資料表、繼承、列層級安全性和遞迴一般資料表表達式 (CTE)。若要深入了解這些 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 資料庫叢集可能需要較大的資料庫執行個體類別** – 根據工作負載，查詢計畫管理可能需要具有 2 個以上 vCPU 的資料庫執行個體類別。`max_worker_processes` 的數目受資料庫執行個體類別大小限制。2-vCPU 資料庫執行個體類別 (例如 db.t3.medium) 提供的 `max_worker_processes` 數目可能不夠指定的工作負載使用。建議若您使用查詢計畫管理，請為 Aurora PostgreSQL 資料庫叢集選擇具有 2 個以上 vCPU 的資料庫執行個體類別。

  當資料庫執行個體類別不支援工作負載時，查詢計畫管理會引發如下錯誤訊息。

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

  在這種情況下，您應該將 Aurora PostgreSQL 資料庫叢集縱向擴展到具有更多記憶體的資料庫執行個體類別大小。如需詳細資訊，請參閱[資料庫執行個體類別的支援資料庫引擎](Concepts.DBInstanceClass.SupportAurora.md)。
+ **已存放在工作階段中的計畫不會受到影響** - 查詢計畫管理提供了一種方式，可在不變更應用程式碼的情況下影響查詢計畫。不過，當一般計畫已存放在現有的工作階段時，而且如果您想要變更其查詢計畫，則必須先在資料庫叢集參數群組中將 `plan_cache_mode` 設為 `force_custom_plan`。
+ 出現下列情況時，`apg_plan_mgmt.dba_plans` 和 `pg_stat_statements` 中的 `queryid` 可能會出現差異：
  + 物件在存放於 apg\$1plan\$1mgmt.dba\$1plans 之後遭到刪除並重新建立。
  + `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` 檢視中。

**計劃基準**  
所指定受管陳述式的核准計劃集。亦即，受管陳述式的所有其 `status` 資料欄在 `dba_plan` 檢視中具有「已核准」的計劃。

**計劃歷史記錄**  
所指定受管陳述式的所有擷取計劃集。計劃歷史記錄包含針對陳述式擷取的所有計劃，不論狀態為何。

**查詢計劃迴歸**  
此情況是最佳化工具在對資料庫環境進行指定的變更 (例如新的 PostgreSQL 版本或統計資料的變更) 之前選擇較不理想的計劃。

## Aurora PostgreSQL 查詢計劃管理版本
<a name="AuroraPostgreSQL.Optimize.overview.versions"></a>

所有目前可用的 Aurora PostgreSQL 版本都支援查詢計劃管理。如需詳細資訊，請參閱《Aurora PostgreSQL 版本資訊》**中的 [Amazon Aurora PostgreSQL 更新](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Updates.html)。

當您安裝 `apg_plan_mgmt` 擴充功能時，查詢計劃管理功能會新增至您的 Aurora PostgreSQL 資料庫叢集。不同版本的 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` 和使用中繼命令 \$1dx 列出擴充功能來連線至執行個體，以識別叢集上執行的版本，如下所示。

```
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 版的擴充功能。只有特定 `apg_plan_mgmt` 版本適用於指定的 Aurora PostgreSQL 版本。在某些情況下，您可能需要將 Aurora PostgreSQL 資料庫叢集升級至新的次要版本，或套用修補程式，以便您可以升級至最新版的查詢計劃管理。輸出中顯示的 `apg_plan_mgmt` 1.0 版來自 Aurora PostgreSQL 10.17 版資料庫叢集，該叢集沒有更新版本的 `apg_plan_mgmt` 可用。在此情況下，Aurora PostgreSQL 資料庫叢集應升級至較新版的 PostgreSQL。

如需將 Aurora PostgreSQL 資料庫叢集升級至新版 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 資料庫叢集設定查詢計劃管理魙涉及安裝擴充功能，以及變更數個資料庫叢集參數設定。您需要 `rds_superuser` 許可，才能安裝 `apg_plan_mgmt` 擴充功能和開啟 Aurora PostgreSQL 資料庫叢集的功能。

安裝擴充功能會建立新角色 `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 資料庫叢集的查詢計劃管理**

下列步驟會針對提交至 Aurora PostgreSQL 資料庫叢集的所有 SQL 陳述式開啟查詢計劃管理。這就是所謂的「自動」**模式。若要進一步了解模式之間的差異，請參閱 [擷取 Aurora PostgreSQL 執行計畫](AuroraPostgreSQL.Optimize.CapturePlans.md)。

1. 前往 [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)，開啟 Amazon RDS 主控台。

1. 針對您的 Aurora PostgreSQL 資料庫叢集建立自訂資料庫叢集參數群組。您需要變更某些參數，才能啟動查詢計劃管理並設定其行為。如需詳細資訊，請參閱[在 Amazon Aurora 中建立資料庫參數群組](USER_WorkingWithParamGroups.Creating.md)。

1. 開啟自訂資料庫叢集參數群組，並將 `rds.enable_plan_management` 參數設定為 `1`，如下圖所示。  
![\[資料庫叢集參數群組的名稱。\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/AuroraUserGuide/images/aurora-qpm-custom-db-cluster-param-change-1.png)

   如需詳細資訊，請參閱[在 Amazon Aurora 中修改資料庫叢集參數群組中的參數](USER_WorkingWithParamGroups.ModifyingCluster.md)。

1. 建立您可以用來在執行個體層級設定查詢計劃參數的自訂資料庫參數群組。如需詳細資訊，請參閱[在 Amazon Aurora 中建立資料庫叢集參數群組](USER_WorkingWithParamGroups.CreatingCluster.md)。

1. 修改 Aurora PostgreSQL 資料庫叢集的寫入器執行個體，來使用自訂資料庫參數群組。如需詳細資訊，請參閱[修改資料庫叢集中的資料庫執行個體](Aurora.Modifying.md#Aurora.Modifying.Instance)。

1. 修改 Aurora PostgreSQL 資料庫叢集，來使用自訂資料庫叢集參數群組。如需詳細資訊，請參閱[使用主控台、CLI 和 API 修改資料庫叢集](Aurora.Modifying.md#Aurora.Modifying.Cluster)。

1. 重新啟動資料庫執行個體來啟用自訂參數群組設定。

1. 使用 `psql` 或 `pgAdmin` 連線至 Aurora PostgreSQL 資料庫叢集的資料庫執行個體端點。下列範例使用 `rds_superuser` 角色的預設 `postgres` 帳戶。

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

1. 為資料庫執行個體建立 `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`。此設定會導致最佳化工具針對每個已計劃或執行兩次或多次的 SQL 陳述式產生計畫。
**注意**  
查詢計劃管理也有您可以用於特定 SQL 陳述式的「手動」**模式。若要進一步了解，請參閱[擷取 Aurora PostgreSQL 執行計畫](AuroraPostgreSQL.Optimize.CapturePlans.md)。

1. 將 `apg_plan_mgmt.use_plan_baselines` 參數的值變更為 "on"。此參數會導致最佳化工具從其計劃基準中選擇陳述式的計劃。如需詳細資訊，請參閱 [使用 Aurora PostgreSQL 受管計劃](AuroraPostgreSQL.Optimize.UsePlans.md)。
**注意**  
您可以修改工作階段的其中任一動態參數值，而不需要重新啟動執行個體。

當您的查詢計劃管理設定完成時，請務必將 `apg_plan_mgmt` 角色授與任何需要檢視、管理或維護查詢計劃的資料庫使用者。

## 升級 Aurora PostgreSQL 查詢計劃管理
<a name="AuroraPostgreSQL.Optimize.Upgrade"></a>

建議您將查詢計劃管理擴充功能升級至 Aurora PostgreSQL 的最新版本。

1. 以擁有 `rds_superuser` 權限的使用者身分，連線至 Aurora PostgreSQL 資料庫叢集的寫入器執行個體。如果您在設定執行個體時保留了預設名稱，則以 `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\$1plan 檢視的已驗證計劃，重新整理共用記憶體中的任何計劃。

   ```
   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` 函數再次分析核准的計畫。比較使用查詢參數繫結前後的效能。若新計畫速度快，您可將其新增至已核准的計畫中。若其比相同參數繫結的另一個計畫快，則可將較慢的計畫標記為 Rejected (拒絕)。

   如需詳細資訊，請參閱[核准較佳計劃](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)。

如需詳細資訊，請參閱 [Ensuring consistent performance after major version upgrades with Amazon Aurora PostgreSQL-Compatible Edition Query Plan Management](https://aws.amazon.com/blogs/database/ensuring-consistent-performance-after-major-version-upgrades-with-amazon-aurora-postgresql-query-plan-management/) (使用 Amazon Aurora PostgreSQL 相容版本查詢計畫管理確保主要版本升級後的效能一致)。

**注意**  
當您使用邏輯複寫或 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 資料庫叢集開啟查詢計劃管理後，最佳化工具會針對其處理多次的任何 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 資料庫叢集列出檢視中目前計劃的詳細資訊。
+ `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 查詢計劃管理提供兩種不同的模式 (自動或手動) 來擷取查詢執行計劃。您可以透過將 `apg_plan_mgmt.capture_plans_baselines` 值設定為 `automatic` 或 `manual` 來選擇模式。您可以使用手動計劃擷取，以擷取特定 SQL 陳述式的執行計劃。您也可以使用自動計劃擷取，以擷取當您的應用程式執行時，已執行兩次或更多次的所有 (或最慢) 計劃。

當擷取計劃時，最佳化工具會將針對受管陳述式而擷取的第一個計劃設為 `approved` 狀態。最佳化工具會將針對受管陳述式而擷取的任何額外計劃設為 `unapproved` 狀態。然而，有時可能會儲存不止一個具有 `approved` 狀態的計劃。當有多個計劃針對某一陳述式被並行建立，而且該陳述式的第一個計劃被遞交之前，可能會發生此種情況。

若要控制可擷取和存放在 `dba_plans` 檢視中的計劃數量上限，請在資料庫執行個體層級參數群組中設定 `apg_plan_mgmt.max_plans` 參數。變更 `apg_plan_mgmt.max_plans` 參數之後需要重新啟動資料庫執行個體，新的值才會生效。如需更多詳細資訊，請參閱 [apg\$1plan\$1mgmt.max\$1plans](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.max_plans) 參數。

## 針對特定 SQL 陳述式來手動擷取計劃
<a name="AuroraPostgreSQL.Optimize.CapturePlans.Manual"></a>

如果您有一組已知的 SQL 陳述式需要管理，請將陳述式放入 SQL 指令碼檔案中，然後手動擷取計劃。以下顯示的 psql 範例示範如何針對一組 SQL 陳述式來手動擷取查詢計劃。

```
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` 檢視中新增一列。

我們建議您在 SQL 指令碼檔案中使用 EXPLAIN 或 EXPLAIN EXECUTE 陳述式。請確認您在參數值中容納了足夠的變化，以擷取您關心的所有計劃。

如果您知道比最佳化工具的最低成本計劃更好的計劃，您可以強制最佳化工具使用更好的計劃。若要這麼做，請指定一個或多個最佳化工具提示。如需更多詳細資訊，請參閱 [使用 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. 在資料庫執行個體層級參數群組中，將 `apg_plan_mgmt.capture_plan_baselines` 設為 `automatic`，以啟用自動計劃擷取。如需詳細資訊，請參閱[修改 Amazon Aurora 中的資料庫參數群組中的參數](USER_WorkingWithParamGroups.Modifying.md)。

1. 當應用程式執行時，最佳化工具會針對至少執行兩次的每個 SQL 陳述式來擷取計劃。

   當應用程式以預設查詢計劃管理參數設定來執行時，最佳化工具會針對至少執行兩次的每個 SQL 陳述式來擷取計劃。使用預設值時擷取所有計劃的執行時間額外負荷非常小，適用於生產環境。

**停用自動計劃擷取**
+ 從資料庫執行個體層級參數群組，將 `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 文件中的[查詢規劃](https://www.postgresql.org/docs/current/runtime-config-query.html)。

下圖顯示當查詢計劃管理處於或不處於作用中狀態時，如何為指定 SQL 陳述式選擇計劃。



![\[Aurora PostgreSQL 的查詢計劃管理工作流程\]](http://docs.aws.amazon.com/zh_tw/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`) 時，使用計劃基準為「off」。計劃在運行之前不會與基準進行比較 (A. 執行最佳化工具的計劃)。
   + 當 `apg_plan_mgmt.use_plan_baselines` 參數設定為 `true` 時，使用計劃基準為「on」。該計劃會使用基準 (6) 進一步評估。

1. 該計劃會與基準中陳述式的其他計劃進行比較。

   1. 如果最佳化工具的計劃位於基準中的計劃，則會檢查其狀態 (7a)。

   1. 如果最佳化工具的計劃不在基準的計劃中，該計劃會以新 `Unapproved` 計劃的形式新增至陳述式的計劃。

1. 系統會檢查計劃的狀態，以決定是否為「未核准」。

   1. 如果計劃的狀態為「未核准」，則計劃的預估成本會與針對未核准執行計劃臨界值指定的成本預估進行比較。
      + 如果計劃的預估成本低於臨界值，則最佳化工具會使用它，即使它是未核准的計劃 (A. 執行最佳化工具的計劃)。一般而言，最佳化工具不會執行未核准的計劃。然而，當 `apg_plan_mgmt.unapproved_plan_execution_threshold` 參數指定成本臨界值，最佳化工具會將「未核准」計劃的成本與臨界值進行比較。如果預估成本低於臨界值，最佳化工具會執行該計劃。如需詳細資訊，請參閱[apg\$1plan\$1mgmt.unapproved\$1plan\$1execution\$1threshold](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.unapproved_plan_execution_threshold)。
      + 如果計劃的預估成本不低於臨界值，則會檢查計劃的其他屬性 (8a)。

   1. 如果計劃的狀態為「未核准」以外的其他屬性，則會勾選其他屬性 (8a)。

1. 最佳化工具不會使用已停用的計劃。亦即 `enable` 屬性設定為 'f' (false) 的計劃。最佳化工具也不會使用狀態為「已拒絕」的計劃。

   最佳化工具無法使用任何無效的計劃。隨著時間的推移，當計劃所依賴的物件 (例如索引或資料表) 被移除或刪除時，計劃可能會變成無效。

   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 資料庫叢集管理員 (具有 `rds_superuser` 權限的人員) 必須明確地將此角色授與需要使用查詢計劃管理的資料庫使用者。

`apg_plan_mgmt` 檢視包含每個資料庫之所有受管 SQL 陳述式的計劃歷史記錄，而這些資料庫位於 Aurora PostgreSQL 資料庫叢集的寫入器執行個體上。此檢視可讓您檢查計劃、其狀態、上次使用時間，以及所有其他相關詳細資訊。

如 [標準化和 SQL 雜湊](AuroraPostgreSQL.Optimize.Start.md#AuroraPostgreSQL.Optimize.Start.hash-and-normalization) 中所討論，每個受管計劃是以結合的 SQL 雜湊值和計劃雜湊值來識別。您可以使用工具 (例如 Amazon RDS Performance Insights) 搭配這些識別符，以追蹤個別計劃效能。如需績效詳情的更多資訊，請參閱[使用 Amazon RDS 績效詳情]( 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)
```

輸出顯示 `rangequery` 陳述式的效能報告，參數繫結為 1 和 10,000。新的未核准計劃 (`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)
```

受管計劃現在包含兩個已核准的計劃，當作陳述式的計劃基線。您也可以呼叫 `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` 計劃，該計劃比陳述式的最佳 `Approved` 計劃還慢至少 10%。

```
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>

查詢最佳化工具精心設計來為所有陳述式尋找最佳計劃，且最佳化工具在大多數情況下會找到好的計劃。不過，有時您可能知道有一個比最佳化工具所產生的計劃好得多的計劃。有兩個建議方法可讓最佳化工具產生理想的計劃，包括使用 `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 變數 – 覆寫一個或多個成本模型參數或其他最佳化工具參數，例如 `from_collapse_limit` 或 `GEQO_threshold`。

當您使用以上其中一項技巧來強制查詢最佳化工具使用計劃時，您也可以使用查詢計劃管理來擷取和強制使用新的計劃。

您可以使用 `pg_hint_plan` 延伸來變更 SQL 陳述式的聯結順序、聯結方法或存取路徑。您使用 SQL 註解搭配特殊的 `pg_hint_plan` 語法，以修改最佳化工具建立計劃的方式。例如，假設有問題的 SQL 陳述式具有雙向聯結。

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

再假設最佳化工具選擇聯結順序 (t1, t2)，但您知道聯結順序 (t2, t1) 更快。下列提示強制最佳化工具使用較快的聯結順序 (t2, t1)。包含 EXPLAIN 會讓最佳化工具為 SQL 陳述式產生計劃，但不需執行陳述式。(未顯示輸出。)

```
/*+ 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>

如果計劃已經超過一個月 (特別是 32 天) 未使用，系統會自動刪除這些計劃。此為 `apg_plan_mgmt.plan_retention_period` 參數的預設設定。您可以延長計劃保留期間，或從值 1 開始的較短期間。判斷上次使用計畫後經過的天數，方法是從目前日期減去 `last_used` 日期。`last_used` 日期是最佳化工具選擇計劃做為最低成本計劃或執行計劃的最近日期。日期是針對 `apg_plan_mgmt.dba_plans` 檢視中的計劃存放的。

建議您刪除長時間未使用或沒有用處的計劃。每個計劃都有 `last_used` 日期，最佳化工具每次執行計劃，或選擇計劃當作陳述式的最低成本計劃時，就會更新此日期。檢查最後 `last_used` 日期，以識別您可以安全刪除的計劃。

下列查詢會傳回三欄表格，其中包含計劃總數、無法刪除的計劃數，以及已順利刪除的計劃數。它具有巢狀查詢，這是一個範例，展示如何使用 `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` 參數。在自訂資料庫參數群組中設定此參數，然後重新啟動資料庫執行個體，讓變更生效。如需更多詳細資訊，請參閱 [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` 函數來刪除或停用無效的計劃。

當計劃所依賴的物件 (例如索引或資料表) 移除時，計劃會變成無效或過時。不過，如果重建已移除的物件，則計劃可能只是暫時無效。如果無效的計劃後來變成有效，您可能會選擇停用無效的計劃，或什麼都不做，而非刪除它。

若要尋找並刪除所有無效且在上週未使用的計劃，請如下使用 `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>

您可以匯出受管計劃，再匯入另一個資料庫執行個體中。

**匯出受管計劃**  
獲授權使用者可以將 `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. 使用 `pg_restore` 命令將 tar 檔案複製到新的資料表。

   ```
   % 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` 擴充功能的偏好設定。您可以在自訂資料庫叢集參數以及與 Aurora PostgreSQL 資料庫叢集關聯的資料庫參數群組中使用這些資料庫參數。這些參數會控制查詢計劃管理功能的行為，以及它對最佳化工具的影響。如需設定查詢計劃管理的詳細資訊，請參閱 [開啟 Aurora PostgreSQL 查詢計劃管理](AuroraPostgreSQL.Optimize.overview.md#AuroraPostgreSQL.Optimize.Enable)。如果 `apg_plan_mgmt` 擴充功能未按照該部分的詳細資訊進行設定，則變更下列參數沒有任何作用。如需修改參數的相關資訊，請參閱 [在 Amazon Aurora 中修改資料庫叢集參數群組中的參數](USER_WorkingWithParamGroups.ModifyingCluster.md) 和 [Amazon Aurora 資料庫執行個體的資料庫參數群組](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` 檢視。根據預設，可儲存的計劃數目上限為 10,000，如 `apg_plan_mgmt.max_plans` 參數所指定。如需參考資訊，請參閱 [apg\$1plan\$1mgmt.max\$1plans](#AuroraPostgreSQL.Optimize.Parameters.max_plans)。

您可以在自訂資料庫叢集參數群組或自訂資料庫參數群組中設定此參數。變更此參數的值不需要重新開機。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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` 檢視中擷取該計畫。

變更此參數的值不需要重新開機。


| 預設 | 允許的值 | Description | 
| --- | --- | --- | 
| 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/zh_tw/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/zh_tw/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Parameters.html)

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

指定 Aurora PostgreSQL 資料庫叢集的寫入器執行個體上可使用查詢計劃管理的資料庫數量上限。預設情況下，查詢計劃管理最多可支援 10 個資料庫。如果執行個體上有 10 個以上的資料庫，您可以變更此設定的值。若要瞭解指定執行個體上有多少資料庫，請使用 `psql` 連線到該執行個體。然後，使用 psql 元命令，`\l`，以列出資料庫。

變更此參數的值時，您必須重新啟動執行個體，設定才會生效。


| 預設 | 允許的值 | Description | 
| --- | --- | --- | 
| 10 | 10-2147483647 | 執行個體上可使用查詢計畫管理的資料庫數量上限。 | 

您可以在自訂資料庫叢集參數群組或自訂資料庫參數群組中設定此參數。

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

設定查詢計畫管理器可以在 `apg_plan_mgmt.dba_plans` 檢視中維護的 SQL 陳述式數量上限。對於所有 Aurora PostgreSQL 版本，我們建議將此參數設定為 `10000` 或更高的值。

您可以在自訂資料庫叢集參數群組或自訂資料庫參數群組中設定此參數。變更此參數的值時，您必須重新啟動執行個體，設定才會生效。


| 預設 | 允許的值 | Description | 
| --- | --- | --- | 
| 10000 | 10-2147483647 | 可儲存於 `apg_plan_mgmt.dba_plans` 檢視的計劃數目上限。 Aurora PostgreSQL 第 10 版及較早版本的預設值為 1000。  | 

如需詳細資訊，請參閱[在 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/zh_tw/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 和以上。

變更此參數的值時，您必須重新啟動執行個體，設定才會生效。


| 預設 | 允許的值 | Description | 
| --- | --- | --- | 
| 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)。

變更此參數的值不需要重新開機。


| 預設 | 允許的值 | Description | 
| --- | --- | --- | 
| 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` 檢視的其中一個「已核准」計劃。根據預設，此參數為 off (false)，導致最佳化工具使用其產生的最低成本計畫，而無需進一步評估。開啟這個參數 (將其設定為 true) 會強制最佳化工具從其計劃基準中選擇陳述式的查詢執行計畫。如需詳細資訊，請參閱[使用 Aurora PostgreSQL 受管計劃](AuroraPostgreSQL.Optimize.UsePlans.md)。若要尋找詳細說明此程序的圖片，請參閱 [最佳化工具如何選擇要執行的計劃](AuroraPostgreSQL.Optimize.UsePlans.md#AuroraPostgreSQL.Optimize.UsePlans.ChoosePlans)。

您可以在自訂資料庫叢集參數群組或自訂資料庫參數群組中設定此參數。變更此參數的值不需要重新開機。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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/zh_tw/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。引發無效輸入的例外狀況。

**參數**


****  

| 參數 | Description | 
| --- | --- | 
| source\$1sql\$1hash  | 與要複製到目標查詢之 plan\$1hash 相關聯的 sql\$1hash ID。 | 
| source\$1plan\$1hash  | 要複製到目標查詢的 plan\$1hash ID。 | 
| target\$1sql\$1hash | 要使用來源計畫雜湊和大綱更新之查詢的 sql\$1hash 識別符。 | 
| target\$1plan\$1hash | 要使用來源計畫雜湊和大綱更新之查詢的 plan\$1hash 識別符。 | 
| 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。

**參數**


****  

| 參數 | 描述 | 
| --- | --- | 
| 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
)
```

**傳回值**

沒有比最佳已核准的計劃更快的計劃數量。

**參數**


****  

| 參數 | 描述 | 
| --- | --- | 
| sql\$1hash | 計劃的受管 SQL 陳述式的 sql\$1hash ID。 | 
| plan\$1hash | 受管計劃的 plan\$1hash ID。使用 NULL 來表示具有相同 sql\$1hash ID 值的所有計劃。 | 
| min\$1speedup\$1factor |  *最小加速因素*可以是一個計劃必須比目前已核准計劃中的最佳計劃快，使其能被核准的倍數。這個因素也可以是一個計劃慢到必須被拒絕或停用的倍數。 這是正浮點值。  | 
| action |  函數執行的動作。有效值如下。大小寫不重要。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Functions.html)  | 

**使用須知**

根據規劃時間加上執行時間比最佳已核准計劃更快的程度是否達到一個可設定的因素，而將指定的計劃設為已核准、已拒絕或已停用。action 參數可能設為 `'approve'` 或 `'reject'`，以自動核准或拒絕符合效能條件的計劃。或者，可能設為 '' (空字串) 以執行效能試驗並產生報告，但不採取任何動作。

對於最近已執行過 `apg_plan_mgmt.evolve_plan_baselines` 函數的計劃，您可以避免漫無目標地重新執行該函數。若要這麼做，請將計劃限制為最近建立，但尚未核准的計劃。或者，您可以避免在有最近 `apg_plan_mgmt.evolve_plan_baselines` 時間戳記的任何已核准計劃上執行 `last_verified` 函數。

進行效能試驗，相對於基線中的其他計劃，比較每個計劃的規劃時間加上執行時間。在某些情況下，陳述式只有一個計劃，而且已核准此計劃。在此情況下，請比較該計劃與不使用任何計劃時的規劃時間加上執行時間。

每個計劃增加的優點 (或缺點) 都記錄在 `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` 計劃。

**參數**


****  

| 參數 | 描述 | 
| --- | --- | 
| 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` 日期。

**注意**  
共用記憶體中的值始終是資料庫叢集中主要資料庫執行個體上的最新值。該值只會定期清空到 `apg_plan_mgmt.dba_plans` 檢視的 `last_used` 欄。

**語法**

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

**傳回值**  
傳回 `last_used` 日期。

**參數**


****  

| 參數 | 描述 | 
| --- | --- | 
| 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。

**參數**


****  

| 參數 | 描述 | 
| --- | --- | 
| 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/zh_tw/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。

**參數**


****  

| 參數 | 描述 | 
| --- | --- | 
| 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/zh_tw/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` 日期大於或等於效能回歸開始的日期。此查詢會識別可能負責效能回歸的計劃或計劃集。您可以使用 `apg_plan_mgmt.get_explain_plan` 與設為 `verbose, hashes` 的 `explainOptionList` 搭配。您也可以使用 `apg_plan_mgmt.evolve_plan_baselines`，來分析計劃和任何可能表現更好的替代計劃。

`update_plans_last_used` 函數只會影響資料庫叢集的主要資料庫執行個體。

## 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)
```

**傳回值**

無效計劃的數量。

**參數**


****  

| 參數 | 描述 | 
| --- | --- | 
| sql\$1hash | 計劃的受管 SQL 陳述式的 sql\$1hash ID。 | 
| plan\$1hash | 受管計劃的 plan\$1hash ID。使用 NULL 來表示具有相同 sql\$1hash ID 值的所有計劃。 | 
| action |  函數對無效計劃執行的動作。有效字串值如下。大小寫不重要。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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 陳述式是包含 VOLATILE 函數的資料操作語言 (DML) 陳述式或 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/zh_tw/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 複本產生的查詢計畫，並將其儲存在 Aurora 資料庫叢集的主要資料庫執行個體上。您可以從所有 Aurora 複本收集查詢計畫，並在主要執行個體的中央永久性資料表中維護一組最佳計畫。然後，您可以在需要時將這些計畫套用至其他複本。這可協助您維護執行計畫的穩定性，並改善資料庫叢集和引擎版本的查詢效能。

**Topics**
+ [先決條件](#AuroraPostgreSQL.QPM.Plancapturereplicas.Prereq)
+ [管理 Aurora 複本的計畫擷取](#AuroraPostgreSQL.QPM.Plancapturereplicas.managing)
+ [故障診斷](#AuroraPostgreSQL.QPM.Plancapturereplicas.Troubleshooting)

## 先決條件
<a name="AuroraPostgreSQL.QPM.Plancapturereplicas.Prereq"></a>

**在 Aurora 複本中開啟 `capture_plan_baselines parameter`** - 將 `capture_plan_baselines` 參數設定為自動或手動，以在 Aurora 複本中擷取計畫。如需更多詳細資訊，請參閱 [apg\$1plan\$1mgmt.capture\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.capture_plan_baselines)。

**安裝 postgres\$1fdw 擴充功能** - 您必須安裝 `postgres_fdw` 外部資料包裝函式，才能在 Aurora 複本中擷取計畫。在每個資料庫中執行下列命令，以安裝擴充功能。

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

## 管理 Aurora 複本的計畫擷取
<a name="AuroraPostgreSQL.QPM.Plancapturereplicas.managing"></a>

**開啟 Aurora 複本的計畫擷取**  
您必須擁有在 Aurora 複本中建立或移除計畫擷取的 `rds_superuser` 權限。如需有關使用者角色和權限的詳細資訊，請參閱[了解 PostgreSQL 角色和權限](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Roles.html)。

若要擷取計畫，請在寫入器資料庫執行個體中呼叫函數 apg\$1plan\$1mgmt.create\$1replica\$1plan\$1capture，如下所示：

```
postgres=> CALL apg_plan_mgmt.create_replica_plan_capture('endpoint', 'password');
```
+ 端點：Aurora 全球資料庫寫入器端點或 cluster\$1endpoint 為 Aurora 複本中的計劃擷取提供容錯移轉支援。

  如需 Aurora 全球資料庫寫入器端點的詳細資訊，請參閱[檢視 Amazon Aurora 全域資料庫的端點](aurora-global-database-connecting.md#viewing-endpoints)。

  如需叢集端點的詳細資訊，請參閱 [Amazon Aurora 的叢集端點](Aurora.Endpoints.Cluster.md)。
+ 密碼 - 我們建議您在建立密碼時遵循以下準則以增強安全性：
  + 必須包含至少 8 個字元。
  + 至少須包含一個大寫字母、一個小寫字母和一個數字。
  + 必須至少有一個特殊字元 (`?`、`!`、`#`、`<`、`>`、`*` 等等)。

**注意**  
如果您變更端點、密碼或連接埠號碼，則必須使用端點和密碼再次執行 `apg_plan_mgmt.create_replica_plan_capture()`，以重新初始化計劃擷取。如果沒有，從 Aurora 複本擷取計畫將會失敗。

**關閉 Aurora 複本的計畫擷取**  
您可以在 Aurora 複本中關閉 `capture_plan_baselines` 參數，方法是在「參數」群組中將其值設定為 `off`。

**移除 Aurora 複本的計畫擷取**  
您可以完全移除 Aurora 複本中的計畫擷取，但在執行之前請務必先確定。若要移除計畫擷取，請呼叫 `apg_plan_mgmt.remove_replica_plan_capture`，如下所示：

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

您必須再次呼叫 apg\$1plan\$1mgmt.create\$1replica\$1plan\$1capture()，以使用端點和密碼在 Aurora 複本中開啟計劃擷取。

## 故障診斷
<a name="AuroraPostgreSQL.QPM.Plancapturereplicas.Troubleshooting"></a>

接下來，如果 Aurora 複本未按預期擷取計畫，您可以找到疑難排解的概念和解決方法。
+ **參數設定** - 檢查 `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 複本中呼叫 apg\$1plan\$1mgmt.delete\$1plan() 後，必須呼叫 apg\$1plan\$1mgmt.reload() 才能使刪除函數生效。這樣可確保變更已成功實施。
+ **密碼** - 您必須依照上述指南在 create\$1replica\$1plan\$1capture() 中輸入密碼。否則，您將收到錯誤訊息。如需詳細資訊，請參閱 [管理 Aurora 複本的計畫擷取](#AuroraPostgreSQL.QPM.Plancapturereplicas.managing)。使用符合要求的另一個密碼。
+ **跨區域連線** - Aurora 全球資料庫也支援 Aurora 複本中的計畫擷取，其中寫入器執行個體和 Aurora 複本可以位於不同的區域。確保您使用 Aurora 全球資料庫寫入器端點，在容錯移轉或轉換事件後維持連線能力。如需 Aurora 全球資料庫端點的詳細資訊，請參閱[檢視 Amazon Aurora 全球資料庫的端點](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)。如果發生跨區域容錯移轉，您必須將端點重新設定為新的主要資料庫叢集端點。
**注意**  
使用叢集端點 (而非 Aurora 全球資料庫寫入器端點) 時，您需要在執行全域容錯移轉或轉換操作之後更新叢集端點。

# 支援資料表分割
<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. 在資料庫叢集參數群組中將 `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` 如何變更，你必須首先了解類似的計畫種類。

在附加節點層級累積的存取方法、去除數字索引名稱和去除數字分割區名稱，其組合必須始終如一，才能將計畫視為相同。計畫中存取的特定分割區並不重要。在下列範例中，會建立具有 4 個分割區的資料表 `tbl_a`。

```
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)
```

在此情況下，從兩個分割區讀取的任何計畫將無法強制執行。除非來自核准計畫中的所有 (存取方法、索引名稱) 組合都可以使用，否則計畫無法強制執行。例如，下列計劃具有不同的計畫雜湊，而且在這些情況下無法強制執行核准計畫：

```
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` 的分割資料表 (其索引名為 `tA_col1_idx1`)，則您無法擁有另一個名為 `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)
```

即使兩個計劃看起來可能相同，但由於子資料表的名稱，其 `Plan Hash` 值也有所不同。資料表名稱因字母字元 (而不只是數字) 的不同，而導致強制執行失敗。