

# 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 설명서의 [Dynamic SQL](https://www.postgresql.org/docs/current/ecpg-dynamic.html)(동적 SQL) 및 [EXECUTE IMMEDIATE](https://www.postgresql.org/docs/current/ecpg-sql-execute-immediate.html)를 참조하세요.
+ 내장된 SQL 명령 및 문. 자세한 내용은 PostgreSQL 설명서의 [Embedded SQL Commands](https://www.postgresql.org/docs/current/ecpg-sql-commands.html)(내장된 SQL 명령)를 참조하세요.
+ 명명된 함수 내의 문. 자세한 내용은 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 설명서의 [Table Partitioning](https://www.postgresql.org/docs/current/ddl-partitioning.html)(테이블 파티셔닝), [Row Security Policies](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)(행 보안 정책), [WITH Queries (Common Table Expressions)](https://www.postgresql.org/docs/current/queries-with.html)(WITH 쿼리(공통 테이블 표현식)) 및 기타 주제를 참조하세요.

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 인스턴스 클래스가 필요할 수 있음** - 워크로드에 따라 쿼리 계획 관리에 vCPU가 2개 이상인 DB 인스턴스 클래스가 필요할 수 있습니다. `max_worker_processes` 수는 DB 인스턴스 클래스 크기에 따라 제한됩니다. 2-vCPU DB 인스턴스 클래스(예: db.t3.medium)에서 제공된 `max_worker_processes`의 수가 지정된 워크로드에 충분하지 않을 수 있습니다. 쿼리 계획 관리를 사용하는 경우 Aurora PostgreSQL DB 클러스터클러스터에 vCPU가 2개 이상인 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\$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` 보기에 하나 이상의 쿼리 실행 계획이 저장되어 있습니다.

**계획 기준**  
주어진 관리형 문에 대해 승인된 계획 세트입니다. 즉, `dba_plan` 뷰에서 `status` 열에 '승인됨'이 있는 관리형 문에 대한 모든 계획입니다.

**계획 기록**  
주어진 관리형 문에 대해 캡처된 모든 계획의 세트입니다. 계획 기록에는 상태와 관계없이 해당 문에 대해 캡처된 모든 계획이 포함됩니다.

**쿼리 계획 회귀**  
최적화 프로그램이 새 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 DB 클러스터에 쿼리 계획 관리 기능이 추가됩니다. PostgreSQL의 버전마다 지원하는 `apg_plan_mgmt` 확장 버전이 다릅니다. 사용 중인 Aurora PostgreSQL 버전의 최신 릴리스로 쿼리 계획 관리 확장을 업그레이드하는 것이 좋습니다.

**참고**  
각 `apg_plan_mgmt` 확장 버전에 대한 릴리스 정보는 Aurora PostgreSQL 릴리스 정보에서** [Aurora PostgreSQL apg\$1plan\$1mgmt extension versions](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraPostgreSQLReleaseNotes/AuroraPostgreSQL.Extensions.html#AuroraPostgreSQL.Extensions.apg_plan_mgmt)(Aurora PostgreSQL apg\$1plan\$1mgmt 확장 버전)를 참조하세요.

인스턴스에 연결하고 `psql` 및 metaccommand \$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 버전의 확장을 사용하고 있음을 보여줍니다. 특정 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. [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/)에서 Amazon 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/ko_kr/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. Aurora PostgreSQL DB 클러스터를 수정하여 사용자 지정 DB 파라미터 그룹을 사용하도록 합니다. 자세한 내용은 [콘솔, CLI, API를 사용하여 DB 클러스터 수정](Aurora.Modifying.md#Aurora.Modifying.Cluster) 섹션을 참조하세요.

1. DB 인스턴스를 재부팅하여 사용자 지정 파라미터 그룹 설정을 활성화합니다.

1. `psql` 또는 `pgAdmin`을 사용하여 Aurora PostgreSQL DB 클러스터의 DB 인스턴스 엔드포인트에 연결합니다. 다음 예에서는 `rds_superuser` 역할에 기본 `postgres` 계정을 사용합니다.

   ```
   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 설명서의 [Template Databases](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` 파라미터의 값을 '켜기'로 변경합니다. 이 파라미터를 사용하면 최적화 프로그램이 계획 기준에서 문에 대한 계획을 선택합니다. 자세한 내용은 [Aurora PostgreSQL 관리형 계획 사용](AuroraPostgreSQL.Optimize.UsePlans.md)를 참조하세요.
**참고**  
인스턴스를 재부팅하지 않고도 세션의 이러한 동적 파라미터 값을 수정할 수 있습니다.

쿼리 계획 관리 설정이 완료되면 쿼리 계획을 보거나 관리하거나 유지 관리해야 하는 모든 데이터베이스 사용자에게 `apg_plan_mgmt` 역할을 부여해야 합니다.

## Aurora PostgreSQL의 쿼리 계획 관리
<a name="AuroraPostgreSQL.Optimize.Upgrade"></a>

사용 중인 Aurora PostgreSQL 버전의 최신 릴리스로 쿼리 계획 관리 확장을 업그레이드하는 것이 좋습니다.

1. Aurora PostgreSQL DB 클러스터의 라이터 인스턴스에 `rds_superuser` 권한을 가진 사용자로 연결합니다. 인스턴스를 설정할 때 기본 이름을 유지했다면 `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) 단원을 참조하세요.

자세한 내용은 [메이저 버전 업그레이드 후 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 쿼리 계획 관리에서는 쿼리 실행 계획을 캡처하기 위한 두 가지 모드, 자동 또는 수동을 제공합니다. `apg_plan_mgmt.capture_plans_baselines`의 값을 `automatic` 또는 `manual`로 설정하여 모드를 선택합니다. 수동 계획 캡처를 사용해 특정 SQL 문에 대한 실행 계획을 캡처할 수 있습니다. 또는 자동 계획 캡처를 사용하여 애플리케이션이 실행될 때 두 번 이상 실행되는 모든 (또는 가장 느린) 계획을 캡처할 수 있습니다.

계획을 캡처하면 최적화 프로그램이 관리형 설명문에 대해 캡처된 첫 번째 계획의 상태를 `approved`로 설정합니다. 최적화 프로그램은 관리형 설명문에 대해 캡처된 추가 계획의 상태를 항상 `unapproved`로 설정합니다. 그러나 두 가지 이상의 계획이 `approved` 상태로 저장되는 경우가 가끔 있을 수 있습니다. 이런 일은 설명문에 대해 여러 계획이 병렬적으로 생성될 때와 설명문의 첫 번째 계획이 커밋되기 전에 발생할 수 있습니다.

`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` 보기에 추가합니다.

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. DB 인스턴스 수준의 파라미터 그룹에서 `apg_plan_mgmt.capture_plan_baselines`를 `automatic`으로 설정하여 자동 계획 캡처를 켭니다. 자세한 내용은 [Amazon Aurora에서 DB 파라미터 그룹의 파라미터 수정](USER_WorkingWithParamGroups.Modifying.md) 섹션을 참조하세요.

1. 애플리케이션이 실행되면 최적화 프로그램이 두 번 이상 실행되는 각 SQL 문에 대해 계획을 캡처합니다.

   애플리케이션이 기본 쿼리 계획 관리 파라미터 설정으로 실행되면 최적화 프로그램이 두 번 이상 실행되는 각 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 쿼리 플래너 비용 견적에 대해 자세히 알아보려면 [쿼리 계획](https://www.postgresql.org/docs/current/runtime-config-query.html)을 참조하세요.

다음 이미지는 쿼리 계획 관리가 활성 상태일 때와 그렇지 않을 때 주어진 SQL 문에 대해 계획이 선택되는 방법을 보여줍니다.



![\[Aurora PostgreSQL 쿼리 계획 관리 워크플로\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/images/aurora-query-plan-mgmt_processing-flow.png)


이 흐름은 다음과 같습니다.

1. 최적화 프로그램은 SQL 문에 대한 최소 비용 계획을 생성합니다.

1. 쿼리 계획 관리가 활성화되어 있지 않으면 최적화 프로그램의 계획(A. Run Optimizer's plan)이 즉시 실행됩니다. 쿼리 계획 관리는 및 매개변수가 모두 기본 설정(각각 "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. Run Optimizer's plan)이 실행됩니다.

      계획이 저장된 계획에 있지만 승인 또는 선호도가 아닌 경우 계획은 캡처 계획 처리(4)로 전송됩니다.

1. 주어진 SQL 문에 대해 처음으로 계획을 캡처할 때 계획의 상태는 항상 승인됨(P1)으로 설정됩니다. 최적화 프로그램은 이후에 동일한 SQL 문에 대해 동일한 계획을 생성하면 해당 계획의 상태가 미승인(P1\$1n)으로 변경됩니다.

   계획이 캡처되고 상태가 업데이트되면 평가가 다음 단계(5)에서 계속됩니다.

1. 계획의 *기준선*은 SQL 문의 기록과 다양한 상태에서의 계획으로 구성됩니다. 쿼리 계획 관리에서는 계획을 선택할 때 다음과 같이 계획 기준선 사용 옵션의 설정 여부에 따라 기준을 고려할 수 있습니다.
   + `apg_plan_mgmt.use_plan_baselines` 파라미터가 기본값(`false`)으로 설정된 경우 계획 기준선 사용은 'off'입니다. 계획은 실행되기 전에 기준선과 비교되지 않습니다(A. Run Optimizer의 계획).
   + `apg_plan_mgmt.use_plan_baselines` 파라미터가 `true`로 설정된 경우 계획 기준선 사용이 'on'입니다. 계획은 기준선(6)을 사용하여 추가로 평가됩니다.

1. 계획은 기준선의 명령문에 대한 다른 계획과 비교됩니다.

   1. 최적화 프로그램의 계획이 베이스라인에 있는 계획들 중이라면 그 상태를 체크한다(7a).

   1. 최적화 프로그램의 계획이 기준선의 계획에 없는 경우 해당 계획은 명령문의 계획에 새 `Unapproved` 계획으로 추가됩니다.

1. 계획의 상태는 승인되지 않은 경우에만 확인하기 위해 확인됩니다.

   1. 계획의 상태가 미승인인 경우 계획의 예상 비용은 승인되지 않은 실행 계획 임계값에 대해 지정된 예상 비용과 비교됩니다.
      + 계획의 예상 비용이 임계값 미만인 경우 미승인 계획(A. Run Optimizer의 계획)이라도 최적화 프로그램은 이를 사용합니다. 일반적으로 최적화 프로그램은 미승인 계획을 실행하지 않습니다. 그러나 파라미터가 비용 임계값을 지정하면 최적화 프로그램은 승인되지 않은 계획의 비용을 임계값과 비교합니다. 예상 비용이 임계값보다 작으면 최적화 프로그램이 계획을 실행합니다. 자세한 내용은 [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 DB 클러스터의 관리자(`rds_superuser` 권한이 있는 사람)는 쿼리 계획 관리를 사용해야 하는 데이터베이스 사용자에게 이 역할을 명시적으로 부여해야 합니다.

`apg_plan_mgmt` 보기에는 Aurora PostgreSQL DB 클러스터의 라이터 인스턴스에 있는 모든 데이터베이스의 모든 관리형 SQL 문에 대한 계획 기록이 포함됩니다. 이 보기를 통해 계획, 상태, 마지막 사용 시점 및 기타 모든 관련 세부 정보를 검토할 수 있습니다.

[정규화 및 SQL 해시](AuroraPostgreSQL.Optimize.Start.md#AuroraPostgreSQL.Optimize.Start.hash-and-normalization)에서 설명한 대로 각 관리형 계획은 SQL 해시 값과 계획 해시 값의 조합으로 식별됩니다. 이러한 식별자를 사용하면 Amazon RDS 성능 개선 도우미와 같은 도구를 사용하여 개별 계획 성능을 추적할 수 있습니다. 성능 개선 도우미에 대한 자세한 내용은 [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)
```

출력에 파라미터 바인딩이 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)
```

이제 관리형 계획에 설명문의 계획 기준인 승인된 계획 두 개가 포함됩니다. 또한 `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>

쿼리 최적화 프로그램은 모든 설명문에 대한 최적 계획을 찾도록 설계되었으며, 대부분의 경우 최적화 프로그램은 좋은 계획을 찾아냅니다. 하지만 경우에 따라 최적화 프로그램에서 생성된 것보다 훨씬 더 나은 계획이 존재한다는 것을 알게 될 수도 있습니다. 최적화 프로그램을 통해 원하는 계획을 생성하기 위한 두 가지 권장 방법은 PostgreSQL에서 `pg_hint_plan` 확장을 사용하거나 Grand Unified Configuration(GUC) 변수를 설정하는 것입니다.
+ `pg_hint_plan` 확장 – PostgreSQL의 `pg_hint_plan` 확장을 사용하여 플래너의 작동 방식을 수정하려면 "힌트(hint)"를 지정합니다. `pg_hint_plan` 확장을 설치하고 사용하는 방법은 [pg\$1hint\$1plan 설명서](https://github.com/ossc-db/pg_hint_plan)를 참조하십시오.
+ GUC 변수 – 하나 이상의 비용 모델 파라미터 또는 다른 최적화 프로그램 파라미터(예: `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>

한 달 이상, 구체적으로 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` 함수를 사용하여 유효하지 않은 계획을 삭제하거나 비활성화할 수 있습니다.

인덱스나 테이블 같은 종속된 객체가 제거되면 계획이 유효하지 않게 되거나 기한 경과 상태가 될 수 있습니다. 하지만 제거된 객체가 다시 생성되는 경우에는 계획이 실시적으로 잘못될 수 있습니다. 유효하지 않은 계획이 나중에 유효 상태가 될 수 있는 경우 유효하지 않은 계획을 삭제하기 보다는 비활성화하거나 아무 작업도 하지 않는 것이 더 나을 수 있습니다.

유효하지 않고 지난 주에 사용한 적이 없는 모든 계획을 찾아서 삭제하려면 다음과 같이 `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. `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` 확장에 대한 기본 설정을 지정할 수 있습니다 사용자 지정 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/ko_kr/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/ko_kr/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/ko_kr/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 및 이전 버전의 기본값은 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/ko_kr/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` 보기에 캡처되고 저장된 승인된 계획 중 하나를 사용해야 함을 지정합니다. 기본적으로 이 파라미터는 꺼져 있으므로(거짓) 최적화 프로그램은 추가 평가 없이 생성한 최소 비용 계획을 사용합니다. 이 파라미터를 켜면(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/ko_kr/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/ko_kr/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을 반환합니다. 입력이 잘못된 경우 예외를 발생시킵니다.

**파라미터**


****  

| 파라미터 | 설명 | 
| --- | --- | 
| 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을 반환합니다.

**파라미터**


****  

| 파라미터 | 설명 | 
| --- | --- | 
| 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. sql\$1hash ID 값이 동일한 모든 계획의 평균을 구하려면 NULL을 사용합니다. | 
| min\$1speedup\$1factor |  *최소 속도 향상 인수*는 계획이 승인되려면 이미 승인된 계획 중 최상의 계획보다 몇 배 더 빨라야 하는지를 지정합니다. 또는 거부되거나 비활성화되려면 몇 배 더 느려야 하는지를 지정할 수도 있습니다. 이 값은 양수 부동 값입니다.  | 
| action |  함수가 수행해야 할 작업입니다. 유효 값에는 다음이 포함됩니다. 대/소문자를 구분하지 않습니다. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Optimize.Functions.html)  | 

**사용 노트**

계획 \$1 실행 시간이 설정한 인수만큼 최상의 승인된 계획보다 더 빠른지 여부에 따라 지정된 계획을 승인됨, 거부됨 또는 비활성화됨으로 설정합니다. 이 작업 파라미터를 `'approve'` 또는 `'reject'`로 설정하여 성능 기준을 충족하는 계획을 자동으로 승인하거나 거부할 수 있습니다. 또는 "(빈 문자열)로 설정하여 성능 실험을 수행한 후 보고서만 생성하고 아무런 작업도 취하지 않을 수 있습니다.

최근에 실행된 계획에 대해 `apg_plan_mgmt.evolve_plan_baselines` 함수를 무의미하게 다시 실행하는 일을 방지할 수 있습니다. 이를 위해서는 최근에 생성한 미승인 계획까지만 계획을 제한하십시오. 또는 최근 `apg_plan_mgmt.evolve_plan_baselines` 타임스탬프가 있는 승인된 계획에서만 `last_verified` 함수를 실행하지 않도록 할 수 있습니다.

성능 실험을 수행하여 기준 내 다른 계획과 각 계획의 계획 \$1 실행 시간을 비교합니다. 경우에 따라서는 설명문에 대해 계획 하나만 있고 해당 계획이 승인된 계획일 수 있습니다. 이러한 경우에는 계획의 계획 \$1 실행 시간과 아무런 계획도 사용하지 않을 때의 계획 \$1 실행 시간을 비교합니다.

각 계획의 증분형 이점(또는 단점)이 `apg_plan_mgmt.dba_plans` 열의 `total_time_benefit_ms` 보기에 기록됩니다. 이 값이 양수이면 기준에 이 계획을 포함할 경우 주목할 만한 성능 개선이 있는 것입니다.

각 후보 계획의 계획 \$1 실행 시간을 수집할 뿐만 아니라, `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` 날짜를 반환합니다.

**참고**  
공유 메모리의 값은 DB 클러스터의 기본 DB 인스턴스에서 항상 최신 상태입니다. 값은 `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/ko_kr/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/ko_kr/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()
```

**반환 값**

없음.

**파라미터**

없음.

**사용 노트**

`dba_plans.last_used` 열에 대항하는 쿼리가 가장 최신 정보를 사용하도록 `update_plans_last_used`를 호출합니다. 만약 `last_used` 날짜가 즉시 업데이트되지 않는다면, 백그라운드 프로세스가 계획 테이블을 `last_used` 날짜로 1시간에 한 번씩(기본값) 업데이트합니다.

예를 들어, 특정 `sql_hash`가 있는 명령문이 느리게 실행되기 시작하면, 성능 회귀 분석이 시작된 이후 해당 명령문에 대해 어떤 계획이 실행되었는지 확인할 수 있습니다. 이렇게 하려면 먼저 공유 메모리의 데이터를 디스크로 플러시하여 `last_used` 날짜가 현재 날짜이고, 그런 다음 성능 회귀가 있는 명령문의 `sql_hash`의 모든 계획을 쿼리합니다. 쿼리에서 `last_used` 날짜가 성능 회귀 분석이 시작된 날짜보다 크거나 같은지 확인하세요. 쿼리는 성과 회귀를 담당할 수 있는 계획 또는 계획 집합을 식별합니다. `apg_plan_mgmt.get_explain_plan`과 `explainOptionList`를 사용하여 `verbose, hashes`로 설정할 수 있습니다. 또한 `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)
```

**반환 값**

잘못된 계획 수.

**파라미터**


****  

| 파라미터 | 설명 | 
| --- | --- | 
| 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/ko_kr/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/ko_kr/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 DB 클러스터의 기본 DB 인스턴스에 저장할 수 있습니다. 모든 Aurora 복제본에서 쿼리 계획을 수집하고 기본 인스턴스의 중앙 영구 테이블에서 최적의 계획 집합을 유지 관리할 수 있습니다. 그런 다음 필요할 때 이 계획을 다른 복제본에 적용할 수 있습니다. 이를 통해 실행 계획의 안정성을 유지하고 DB 클러스터 및 엔진 버전 전반의 쿼리 성능을 개선할 수 있습니다.

**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` 켜기** - Aurora 복제본에서 계획을 캡처하려면 `capture_plan_baselines` 파라미터를 자동 또는 수동으로 설정합니다. 자세한 내용은 [apg\$1plan\$1mgmt.capture\$1plan\$1baselines](AuroraPostgreSQL.Optimize.Parameters.md#AuroraPostgreSQL.Optimize.Parameters.capture_plan_baselines) 단원을 참조하십시오.

**postgres\$1fdw 확장 설치** - Aurora 복제본에서 계획을 캡처하려면 `postgres_fdw` 외부 데이터 래퍼 확장을 설치해야 합니다. 각 데이터베이스에서 다음 명령을 실행하여 확장을 설치합니다.

```
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)를 참조하세요.

계획을 캡처하려면 다음과 같이 라이터 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 복제본의 계획 캡처에 대한 장애 조치 지원을 제공합니다.

  Aurora Global Database 라이터 엔드포인트에 대한 자세한 내용은 [Amazon Aurora Global Database의 엔드포인트 보기](aurora-global-database-connecting.md#viewing-endpoints) 섹션을 참조하시기 바랍니다.

  클러스터 엔드포인트에 대한 자세한 내용은 [Amazon Aurora용 클러스터 엔드포인트](Aurora.Endpoints.Cluster.md) 섹션을 참조하세요.
+ 암호 - 보안을 강화하려면 암호를 생성할 때 아래 지침을 따르는 것이 좋습니다.
  + 최소 8개의 문자를 포함해야 합니다.
  + 최소한 대문자 1개, 소문자 1개 및 숫자 1개를 포함해야 합니다.
  + 하나 이상의 특수 문자(`?`, `!`, `#`, `<`, `>`, `*` 등)가 있어야 합니다.

**참고**  
엔드포인트, 암호 또는 포트 번호를 변경하는 경우 엔드포인트 및 암호를 사용하여 `apg_plan_mgmt.create_replica_plan_capture()`를 다시 실행하여 계획 캡처를 다시 초기화해야 합니다. 이렇게 하지 않으면 Aurora 복제본에서 계획을 캡처하는 데 실패합니다.

**Aurora 복제본의 계획 캡처 끄기**  
파라미터 그룹에서 값을 `off`로 설정하여 Aurora 복제본의 `capture_plan_baselines` 파라미터를 끌 수 있습니다.

**Aurora 복제본의 계획 캡처 제거**  
Aurora 복제본에서 계획 캡처를 완전히 제거할 수 있지만 먼저 확인할 것이 있습니다. 계획 캡처를 제거하려면 다음과 같이 `apg_plan_mgmt.remove_replica_plan_capture`를 호출합니다.

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

Aurora 복제본에서 계획 캡처를 설정하려면 엔드포인트와 암호를 사용하여 apg\$1plan\$1mgmt.create\$1replica\$1plan\$1capture()를 다시 호출해야 합니다.

## 문제 해결
<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 Global Database에서도 지원됩니다. Aurora Global Database에서는 라이터 인스턴스와 Aurora 복제본이 서로 다른 리전에 있을 수 있습니다. 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\$13단계를 반복합니다.

이런 파라미터에 대한 자세한 내용은 [Aurora PostgreSQL 쿼리 계획 관리를 위한 파라미터 참조](AuroraPostgreSQL.Optimize.Parameters.md) 섹션을 참조하세요.

## 테이블 파티션에 대한 계획 캡처
<a name="AuroraPostgreSQL.QPM.Partitiontable.capture"></a>

QPM에서는 다양한 계획이 `plan_hash` 값으로 구분됩니다. `plan_hash`가 어떻게 변하는지 이해하려면 먼저 비슷한 종류의 계획을 이해해야 합니다.

계획이 동일한 것으로 간주되려면 Append 노드 수준에서 누적된 액세스 방법, 숫자 제거 인덱스 이름 및 숫자 제거 파티션 이름의 조합이 일정해야 합니다. 계획에서 액세스하는 특정 파티션은 중요하지 않습니다. 다음 예제에서는 파티션이 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)
```

상위 수준에서 액세스 방법, 숫자 제거 인덱스 이름 및 숫자 제거 파티션 이름이 `SeqScan tbl_a`, `IndexScan (i_idx) tbl_a`이므로 다음 3가지 계획도 동일한 것으로 간주됩니다.

```
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` 값이 다릅니다. 테이블 이름이 숫자만이 아닌 영문자에 따라 다양하므로 적용이 실패합니다.