

# 使用 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_cn/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. 如果计划的状态为“未批准”，则将该计划的估计成本与为未批准的执行计划阈值指定的成本估计值进行比较。
      + 如果计划的估计成本低于阈值，则即使它是未批准的计划，优化程序也会使用它（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. 运行优化程序的计划）。