

# Aurora PostgreSQL でクエリパフォーマンスを最適化する
<a name="AuroraPostgreSQL.optimizing.queries"></a>

クエリパフォーマンスの最適化が重要なのは、より少ないリソースを使用しながらデータベースをより迅速かつ効率的に実行するのに役立ち、ユーザーエクスペリエンスの向上と運用コストの削減につながるためです。Amazon Aurora PostgreSQL には、PostgreSQL ワークロードのクエリパフォーマンスを最適化するのに役立ついくつかの機能があります。

**Topics**
+ [Amazon Optimized Reads による Aurora PostgreSQL のクエリパフォーマンスの向上](AuroraPostgreSQL.optimized.reads.md)
+ [Aurora PostgreSQL で相関サブクエリを最適化する](apg-correlated-subquery.md)
+ [アダプティブ結合を使用したクエリパフォーマンスの向上](user-apg-adaptive-join.md)
+ [共有プランキャッシュの使用](apg-shared-plan-cache.md)

# Amazon Optimized Reads による Aurora PostgreSQL のクエリパフォーマンスの向上
<a name="AuroraPostgreSQL.optimized.reads"></a>

Aurora Optimized Reads で Aurora PostgreSQL のクエリ処理を高速化できます。Aurora Optimized Reads を使用する Aurora PostgreSQL DB インスタンスは、DB インスタンスのメモリ容量を超える大規模なデータセットを持つアプリケーションのクエリレイテンシーを最大 8 倍改善し、コストを最大 30% 削減します。

**Topics**
+ [PostgreSQL の Aurora Optimized Reads の概要](#AuroraPostgreSQL.optimized.reads.overview)
+ [Aurora Optimized Reads の使用](#AuroraPostgreSQL.optimized.reads.using)
+ [Aurora Optimized Reads のユースケース](#AuroraPostgreSQL.optimized.reads.usecases)
+ [Aurora Optimized Reads を使用する DB インスタンスのモニタリング](#AuroraPostgreSQL.optimized.reads.monitoring)
+ [Aurora Optimized Reads のベストプラクティス](#AuroraPostgreSQL.optimized.reads.bestpractices)

## PostgreSQL の Aurora Optimized Reads の概要
<a name="AuroraPostgreSQL.optimized.reads.overview"></a>

Aurora Optimized Reads は、Graviton ベースの R6gd、R8gd、および Intel ベースの R6id インスタンスと不揮発性メモリエクスプレス (NVMe) ストレージを備えた DB クラスターを作成するときに、デフォルトで使用できます。以下の PostgreSQL バージョンから入手できます。
+ R8gd インスタンスの 14.12 以降のバージョン、15.7 以降のバージョン、16.3 以降のバージョン、17.4 以降のバージョン
+ R6gd および R6id インスタンスの 14.9 以降のバージョン、15.4 以降のバージョン、16.1 以降のすべてのバージョン

Aurora Optimized Reads は、階層型キャッシュと一時オブジェクトの 2 つの機能をサポートしています。

**Optimized Reads 対応階層型キャッシュ** - 階層型キャッシュを使用すると、DB インスタンスのキャッシュ容量をインスタンスメモリの 5 倍まで拡張できます。これにより、トランザクションが一貫した最新のデータがキャッシュに自動的に保持され、外部の結果セットベースのキャッシュソリューションによるデータ流通管理のオーバーヘッドからアプリケーションが解放されます。これまで Aurora ストレージからデータを取得していたクエリのレイテンシーが最大 8 倍向上します。

Aurora では、デフォルトパラメータグループでの `shared_buffers` の値は、通常、使用可能なメモリの約 75% に設定されます。ただし、r8gd、r6gd および r6id インスタンスタイプの場合、Aurora は Optimized Reads キャッシュのメタデータをホストするため、`shared_buffers` スペースを 4.5% 削減します。

**Optimized Reads 対応一時オブジェクト** - 一時オブジェクトを使用すると、PostgreSQL によって生成された一時ファイルをローカルの NVMe ストレージに配置することで、クエリ処理を高速化できます。これにより、ネットワーク経由の Elastic Block Storage (EBS) へのトラフィックが減少します。DB インスタンスで使用可能なメモリ容量に収まらない大量のデータをソート、結合、またはマージする高度なクエリでは、レイテンシーとスループットが最大 2 倍向上します。

Aurora I/O 最適化クラスターでは、Optimized Reads は NVMe ストレージ上の階層型キャッシュと一時オブジェクトの両方を利用します。Optimized Reads 対応階層型キャッシュ機能により、Aurora はインスタンスメモリの 2 倍を一時オブジェクトに、ストレージの約 10% を内部オペレーションに、残りのストレージを階層型キャッシュとして割り当てます。Aurora スタンダードクラスターでは、Optimized Reads は一時オブジェクトのみを使用します。

Aurora I/O 最適化クラスターでは、インスタンスレベルで動的パラメータ `aurora_temp_space_size` を使用して、Optimized Reads が有効な一時オブジェクトに割り当てられたスペースのサイズを変更できます。この変更機能は、以下の PostgreSQL バージョンから入手できます。
+ 16.8 以降のすべてのバージョン
+ 15.12 以降の 15 バージョン
+ 14.17 以降の 14 バージョン

このパラメータを使用すると、データベースエンジンの再起動を必要とせずに、インスタンスメモリの容量を 2 倍から 6 倍まで変更できます。一時オブジェクトスペースを拡張すると、同時実行ワークロードに関係なく、変更はすぐに有効になります。ただし、スペースを減らすと、新しいサイズリクエストに対応するために、一時オブジェクトに十分な未使用のスペースがある場合にのみ調整が完了します。Optimized Reads 対応一時オブジェクトのサイズを変更すると、階層型キャッシュは使用可能なスペースを使用するように自動的に調整されます。

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

**注記**  
NVMe ベースの DB インスタンスクラスで IO 最適化クラスターとスタンダードクラスターを切り替えると、データベースエンジンがすぐに再起動します。

Aurora PostgreSQL では、一時オブジェクトが格納されるテーブルスペースを設定するのに `temp_tablespaces` パラメータを使用します。

一時オブジェクトが設定されているかどうかを確認するには、次のコマンドを使用します。

```
postgres=> show temp_tablespaces;
temp_tablespaces
---------------------
aurora_temp_tablespace
(1 row)
```

`aurora_temp_tablespace` は、NVMe ローカルストレージを指す Aurora によって設定された表領域です。このパラメータは変更できません。また、Amazon EBS ストレージに切り替えることはできません。

Optimized Reads キャッシュがオンになっているかどうかを確認するには、次のコマンドを使用します。

```
postgres=> show shared_preload_libraries;
                 shared_preload_libraries
--------------------------------------------------------
rdsutils,pg_stat_statements,aurora_optimized_reads_cache
```

## Aurora Optimized Reads の使用
<a name="AuroraPostgreSQL.optimized.reads.using"></a>

NVMe ベースの DB インスタンスを使用して Aurora PostgreSQL DB インスタンスをプロビジョニングすると、DB インスタンスは自動的に Aurora Optimized Reads を使用します。

RDS Optimized Reads をオンにするには、次のいずれかの操作を行います。
+ NVMe ベースの DB インスタンスクラスの 1 つを使用して、Aurora PostgreSQL DB クラスターを作成します。詳細については、「[Amazon Aurora DB クラスターの作成](Aurora.CreateInstance.md)」を参照してください。
+ NVMe ベースの DB インスタンスクラスの 1 つを使用して、既存の Aurora PostgreSQL DB クラスターを変更します。詳細については、「[Amazon Aurora DB クラスターの変更](Aurora.Modifying.md)」を参照してください。

Aurora Optimized Reads は、ローカル NVMe SSD ストレージのある DB インスタンスクラスの 1 つ以上がサポートされているすべての AWS リージョン で使用できます。詳細については、「[Amazon Aurora DB インスタンスクラス](Concepts.DBInstanceClass.md)」を参照してください。

最適化されていない読み取り Aurora インスタンスに戻すには、Aurora インスタンスの DB インスタンスクラスを、データベースワークロードの NVMe エフェメラルストレージがない同様のインスタンスクラスに変更します。例えば、現在の DB インスタンスクラスが db.r6gd.4xlarge の場合、db.r6g.4xlarge を選択して元に戻します。詳細については、「[Aurora DB インスタンスを変更する](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html)」を参照してください。

## Aurora Optimized Reads のユースケース
<a name="AuroraPostgreSQL.optimized.reads.usecases"></a>

**Optimized Reads 対応階層型キャッシュ**

以下に、階層型キャッシュで Optimized Reads を使用することでメリットが得られるユースケースをいくつか紹介します。
+ 支払い処理、請求、E コマースなど、厳格なパフォーマンス SLA を備えたインターネットスケールアプリケーション。
+ メトリクスやデータ収集のために何百ものポイントクエリを実行するリアルタイムレポートダッシュボード。
+ pgvector 拡張機能を備えた生成 AI アプリケーションにより、何百万ものベクター埋め込みから正確な近傍または最近傍を検索できます。

**Optimized Reads 対応一時オブジェクト**

以下に、一時オブジェクトで Optimized Reads を使用することでメリットが得られるユースケースをいくつか紹介します。
+ テーブル共通式 (CTE)、派生テーブル、グループ化オペレーションを含む分析クエリ。
+ アプリケーションの最適化されていないクエリを処理するリードレプリカ。
+ GROUP BY や ORDER BY などの複雑な操作を伴うオンデマンドまたは動的なレポートクエリで、常に適切なインデックスを使用できるとは限らないもの。
+ ソート用の `CREATE INDEX` または `REINDEX` 操作。
+ 内部の一時テーブルを使用するその他のワークロード。

## Aurora Optimized Reads を使用する DB インスタンスのモニタリング
<a name="AuroraPostgreSQL.optimized.reads.monitoring"></a>

 Aurora Optimized Reads 対応階層型キャッシュを使用するクエリは、次の例のように EXPLAIN コマンドでモニタリングできます。

```
Postgres=> EXPLAIN (ANALYZE, BUFFERS) SELECT c FROM sbtest15 WHERE id=100000000                   

QUERY PLAN
--------------------------------------------------------------------------------------
 Index Scan using sbtest15_pkey on sbtest15  (cost=0.57..8.59 rows=1 width=121) (actual time=0.287..0.288 rows=1 loops=1)
   Index Cond: (id = 100000000)
   Buffers: shared hit=3 read=2 aurora_orcache_hit=2
   I/O Timings: shared/local read=0.264
 Planning:
   Buffers: shared hit=33 read=6 aurora_orcache_hit=6
   I/O Timings: shared/local read=0.607
 Planning Time: 0.929 ms
 Execution Time: 0.303 ms
(9 rows)
Time: 2.028 ms
```

**注記**  
説明プランの `Buffers` セクションにある `aurora_orcache_hit` および`aurora_storage_read` フィールドは、Optimized Reads が有効で、値が 0 より大きい場合にのみ表示されます。読み取りフィールドは、`aurora_orcache_hit` と `aurora_storage_read` フィールドの合計です。

Aurora Optimized Reads を使用する DB インスタンスは、次の CloudWatch メトリクスでモニタリングできます。
+ `AuroraOptimizedReadsCacheHitRatio`
+ `FreeEphemeralStorage`
+ `ReadIOPSEphemeralStorage`
+ `ReadLatencyEphemeralStorage`
+ `ReadThroughputEphemeralStorage`
+ `WriteIOPSEphemeralStorage`
+ `WriteLatencyEphemeralStorage`
+ `WriteThroughputEphemeralStorage`

これらのメトリクスでは、利用可能なインスタンスストアストレージ、IOPS、スループットに関するデータを提供します。これらのメトリクスの詳細については、「」を参照してください。[Amazon Aurora のインスタンスレベルのメトリクス](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)

`pg_proctab` 拡張機能を使用して NVMe ストレージをモニタリングすることもできます。

```
postgres=>select * from pg_diskusage();

major | minor |       devname       | reads_completed | reads_merged | sectors_read | readtime | writes_completed | writes_merged | sectors_written | writetime | current_io | iotime  | totaliotime
------+-------+---------------------+-----------------+--------------+--------------+----------+------------------+---------------+-----------------+-----------+------------+---------+-------------
      |       | rdstemp             |           23264 |            0 |       191450 |    11670 |          1750892 |             0 |        24540576 |    819350 |          0 | 3847580 |      831020
      |       | rdsephemeralstorage |           23271 |            0 |       193098 |     2620 |           114961 |             0 |        13845120 |    130770 |          0 |  215010 |      133410
(2 rows)
```

## Aurora Optimized Reads のベストプラクティス
<a name="AuroraPostgreSQL.optimized.reads.bestpractices"></a>

Aurora Optimized Reads を使用するベストプラクティスは次のとおりです。
+ CloudWatch メトリクスの `FreeEphemeralStorage` を使用して、インスタンスストアで使用可能なストレージ容量をモニタリングします。DB インスタンスのワークロードが原因でインスタンスストアが上限に達している場合は、同時実行数と一時オブジェクトを頻繁に使用するクエリを調整するか、より大きな DB インスタンスクラスを使用するように変更します。
+ CloudWatch メトリクスをモニタリングして、Optimized Reads キャッシュヒットレートを確認します。VACUUM のようなオペレーションでは、多数のブロックを非常に素早く変更します。これにより、ヒットレートが一時的に低下する可能性があります。`pg_prewarm` 拡張機能を使用すると、データをバッファキャッシュにロードできます。これにより、Aurora はそれらのブロックの一部を Optimized Reads キャッシュに事前に書き込むことができます。
+ クラスターキャッシュ管理 (CCM) を有効にすると、フェイルオーバーターゲットとして使用される Tier-0 リーダーのバッファキャッシュと階層型キャッシュをウォームアップできます。CCM を有効にすると、バッファキャッシュが定期的にスキャンされ、エビクションの対象となるページが階層型キャッシュに書き込まれます。CCM の詳細については、「[Aurora PostgreSQL のクラスターキャッシュ管理によるフェイルオーバー後の高速リカバリ](AuroraPostgreSQL.cluster-cache-mgmt.md)」を参照してください。

# Aurora PostgreSQL で相関サブクエリを最適化する
<a name="apg-correlated-subquery"></a>

 相関サブクエリは、外部クエリのテーブルの列を参照します。外部クエリが返す 1 行ごとに 1 回評価されます。次の例では、サブクエリはテーブル ot の列を参照します。このテーブルはサブクエリの FROM 句に含まれませんが、外部クエリの FROM 句で参照されます。テーブル ot の行数が 100 万行の場合、サブクエリは 100 万回評価される必要があります。

```
SELECT ot.a, ot.b FROM ot WHERE ot.b < (SELECT AVG(it.b) FROM it WHERE it.a = ot.a);
```

**注記**  
サブクエリ変換とサブクエリキャッシュは、バージョン 16.8 以降の Aurora PostgreSQL で使用できますが、Babelfish for Aurora PostgreSQL は 4.2.0 からのこれらの機能をサポートしています。
Babelfish for Aurora PostgreSQL バージョン 4.6.0 および 5.2.0 以降では、以下のパラメータがこれらの機能を制御します。  
 babelfishpg\$1tsql.apg\$1enable\$1correlated\$1scalar\$1transform 
 babelfishpg\$1tsql.apg\$1enable\$1subquery\$1cache 
デフォルトでは、どちらのパラメータも有効になっています。

## サブクエリ変換を使用した Aurora PostgreSQL クエリのパフォーマンスの向上
<a name="apg-corsubquery-transformation"></a>

Aurora PostgreSQL は、相関サブクエリを同等の外部結合に変換して高速化できます。この最適化は、次の 2 種類の相関サブクエリに適用されます。
+ 単一の集計値を返し、SELECT リストに表示されるサブクエリ。

  ```
  SELECT ot.a, ot.b, (SELECT AVG(it.b) FROM it WHERE it.a = ot.a) FROM ot;
  ```
+ 単一の集計値を返し、WHERE 句に表示されるサブクエリ。

  ```
  SELECT ot.a, ot.b FROM ot WHERE ot.b < (SELECT AVG(it.b) FROM it WHERE it.a = ot.a);
  ```

### サブクエリでの変換の有効化
<a name="apg-corsub-transform"></a>

 相関サブクエリを同等の外部結合に変換できるようにするには、`apg_enable_correlated_scalar_transform` パラメータを `ON` に設定します。このパラメータのデフォルト値は `OFF` です。

パラメータ設定は、クラスターまたはインスタンスのパラメータグループで変更できます。詳細については[Amazon Aurora のパラメータグループ](USER_WorkingWithParamGroups.md)を参照してください。

または、次のコマンドを呼び出すことで、現在のセッションのみの設定を構成できます。

```
SET apg_enable_correlated_scalar_transform TO ON;
```

### 変換の検証
<a name="apg-corsub-transform-confirm"></a>

EXPLAIN コマンドを使用して、相関サブクエリがクエリプラン内の外部結合に変換されているかどうかを確認します。

 変換を有効にすると、該当する相関サブクエリ部分が外部結合に変換されます。例えば、次のようになります。

```
postgres=> CREATE TABLE ot (a INT, b INT);
CREATE TABLE
postgres=> CREATE TABLE it (a INT, b INT);
CREATE TABLE

postgres=> SET apg_enable_correlated_scalar_transform TO ON;
SET
postgres=> EXPLAIN (COSTS FALSE) SELECT ot.a, ot.b FROM ot WHERE ot.b < (SELECT AVG(it.b) FROM it WHERE it.a = ot.a);

                         QUERY PLAN
--------------------------------------------------------------
 Hash Join
   Hash Cond: (ot.a = apg_scalar_subquery.scalar_output)
   Join Filter: ((ot.b)::numeric < apg_scalar_subquery.avg)
   ->  Seq Scan on ot
   ->  Hash
         ->  Subquery Scan on apg_scalar_subquery
               ->  HashAggregate
                     Group Key: it.a
                     ->  Seq Scan on it
```

GUC パラメータが `OFF` に設定されている場合、同じクエリは変換されません。プランには外部結合はなく、代わりにサブプランがあります。

```
postgres=> SET apg_enable_correlated_scalar_transform TO OFF;
SET
postgres=> EXPLAIN (COSTS FALSE) SELECT ot.a, ot.b FROM ot WHERE ot.b < (SELECT AVG(it.b) FROM it WHERE it.a = ot.a);
                QUERY PLAN
----------------------------------------
 Seq Scan on ot
   Filter: ((b)::numeric < (SubPlan 1))
   SubPlan 1
     ->  Aggregate
           ->  Seq Scan on it
                 Filter: (a = ot.a)
```

### 制限事項
<a name="apg-corsub-transform-limitations"></a>
+ サブクエリは SELECT リストまたは where 句の中の条件の 1 つに存在する必要があります。そうでない場合、変換されません。
+ サブクエリは集計関数を返す必要があります。ユーザー定義の集計関数は変換ではサポートされていません。
+ 戻り式が単純な集計関数ではないサブクエリは変換されません。
+ サブクエリ WHERE 句の相関条件は、単純な列参照である必要があります。そうでない場合、変換されません。
+ サブクエリ where 句の相関条件は、単純な等価述語である必要があります。
+ サブクエリに HAVING 句または GROUP BY 句を含めることはできません。
+ サブクエリの where 句には、AND と組み合わせた 1 つ以上の述語を含めることができます。

**注記**  
変換のパフォーマンスへの影響は、スキーマ、データ、ワークロードによって異なります。変換を伴う相関サブクエリの実行は、外部クエリによって生成される行数が増えるにつれてパフォーマンスが大幅に向上する可能性があります。この機能を本番環境で有効にする前に、実際のスキーマ、データ、ワークロードを使用して本番環境でテストすることを強くお勧めします。

## サブクエリキャッシュを使用して Aurora PostgreSQL クエリのパフォーマンスを向上させる
<a name="apg-subquery-cache"></a>

 Aurora PostgreSQL は、相関サブクエリの結果を保存するためのサブクエリキャッシュをサポートしています。この機能は、サブクエリの結果が既にキャッシュにある場合に、相関サブクエリの繰り返しの実行をスキップします。

### サブクエリキャッシュについて
<a name="apg-subquery-cache-understand"></a>

 PostgreSQL の Memoize ノードは、サブクエリキャッシュの重要な部分です。Memoize ノードは、入力パラメータ値からクエリ結果の行にマッピングするために、ローカルキャッシュにハッシュテーブルを維持します。ハッシュテーブルのメモリ制限は、work\$1mem と hash\$1mem\$1multiplier の積です。詳細については、「[Resource Consumption](https://www.postgresql.org/docs/16/runtime-config-resource.html)」を参照してください。

 クエリの実行中、サブクエリキャッシュはキャッシュヒットレート (CHR) を使用して、キャッシュがクエリのパフォーマンスを向上させているかどうかを推定し、クエリの実行時にキャッシュを引き続き使用するかどうかを決定します。CHR は、キャッシュヒット数とリクエストの合計数の比率です。例えば、相関サブクエリを 100 回実行する必要があり、それらの実行結果のうち 70 個をキャッシュから取得できる場合、CHR は 0.7 です。

キャッシュミスの apg\$1subquery\$1cache\$1check\$1interval 数ごとに、CHR が apg\$1subquery\$1cache\$1hit\$1rate\$1threshold より大きいかどうかをチェックすることで、サブクエリキャッシュの利点が評価されます。そうでない場合、キャッシュはメモリから削除され、クエリの実行はキャッシュされていない元のサブクエリの再実行に戻ります。

### サブクエリのキャッシュ動作を制御するパラメータ
<a name="apg-subquery-cache-parameters"></a>

次の表に、サブクエリキャッシュの動作を制御するパラメータを示します。


|  パラメータ  | 説明  | デフォルト | 許可  | 
| --- | --- | --- | --- | 
| apg\$1enable\$1subquery\$1cache  | 相関スカラーサブクエリのキャッシュの使用を有効にします。  | VOFF  | ON、OFF | 
| apg\$1subquery\$1cache\$1check\$1interval  | サブクエリのキャッシュヒットレートを評価する頻度をキャッシュミスの数で設定します。  | 500  | 0-2147483647 | 
| apg\$1subquery\$1cache\$1hit\$1rate\$1threshold  | サブクエリのキャッシュヒットレートのしきい値を設定します。  | 0.3  | 0.0–1.0 | 

**注記**  
`apg_subquery_cache_check_interval` の値を大きくすると、CHR ベースのキャッシュメリットの推定の精度は向上しますが、キャッシュテーブルに `apg_subquery_cache_check_interval` 行が含まれるまで CHR は評価されないため、キャッシュオーバーヘッドが増加します。
`apg_subquery_cache_hit_rate_threshold` の値が大きいほど、サブクエリキャッシュの放棄と、キャッシュされていない元のサブクエリの再実行に戻るように偏ります。

パラメータ設定は、クラスターまたはインスタンスのパラメータグループで変更できます。詳細については[Amazon Aurora のパラメータグループ](USER_WorkingWithParamGroups.md)を参照してください。

または、次のコマンドを呼び出すことで、現在のセッションのみの設定を構成できます。

```
SET apg_enable_subquery_cache TO ON;
```

### Aurora PostgreSQL でサブクエリキャッシュを有効にする
<a name="apg-subquery-cache-turningon"></a>

サブクエリキャッシュを有効にすると、Aurora PostgreSQL はキャッシュを適用してサブクエリの結果を保存します。クエリプランの SubPlan の下に Memoize ノードが含まれるようになります。

 例えば、次のコマンドシーケンスは、サブクエリキャッシュのない単純な相関サブクエリの推定クエリ実行プランを示しています。

```
postgres=> SET apg_enable_subquery_cache TO OFF;
SET
postgres=> EXPLAIN (COSTS FALSE) SELECT ot.a, ot.b FROM ot WHERE ot.b < (SELECT it.b FROM it WHERE it.a = ot.a);

             QUERY PLAN
------------------------------------
 Seq Scan on ot
   Filter: (b < (SubPlan 1))
   SubPlan 1
     ->  Seq Scan on it
           Filter: (a = ot.a)
```

`apg_enable_subquery_cache` を有効にすると、クエリプランの SubPlan ノードの下に Memoize ノードが含まれ、サブクエリがキャッシュを使用する予定であることを示します。

```
postgres=> SET apg_enable_subquery_cache TO ON;
SET
postgres=> EXPLAIN (COSTS FALSE) SELECT ot.a, ot.b FROM ot WHERE ot.b < (SELECT it.b FROM it WHERE it.a = ot.a);

             QUERY PLAN
------------------------------------
 Seq Scan on ot
   Filter: (b < (SubPlan 1))
   SubPlan 1
     ->  Memoize
           Cache Key: ot.a
           Cache Mode: binary
           ->  Seq Scan on it
                 Filter: (a = ot.a)
```

 実際のクエリ実行プランには、キャッシュヒットやキャッシュミスなど、サブクエリキャッシュの詳細が含まれています。次の出力は、上記のクエリ例でテーブルにいくつかの値を挿入した後の、実際のクエリ実行プランを示しています。

```
postgres=> EXPLAIN (COSTS FALSE, TIMING FALSE, ANALYZE TRUE) SELECT ot.a, ot.b FROM ot WHERE ot.b < (SELECT it.b FROM it WHERE it.a = ot.a);
            QUERY PLAN
-----------------------------------------------------------------------------
 Seq Scan on ot (actual rows=2 loops=1)
   Filter: (b < (SubPlan 1))
   Rows Removed by Filter: 8
   SubPlan 1
     ->  Memoize (actual rows=0 loops=10)
           Cache Key: ot.a
           Cache Mode: binary
           Hits: 4  Misses: 6  Evictions: 0  Overflows: 0  Memory Usage: 1kB
           ->  Seq Scan on it (actual rows=0 loops=6)
                 Filter: (a = ot.a)
                 Rows Removed by Filter: 4
```

キャッシュヒット数の合計は 4 で、キャッシュミス数の合計は 6 です。ヒットとミスの合計数が Memoize ノードのループ数よりも少ない場合、CHR 評価が成功せず、キャッシュがクリーンアップされ、ある時点で中止されたことを意味します。その後、サブクエリ実行は元のキャッシュされていない再実行に戻されます。

### 制限事項
<a name="apg-subquery-cache-limitations"></a>

サブクエリキャッシュは、相関サブクエリの特定のパターンをサポートしていません。サブクエリキャッシュが有効になっている場合でも、これらのタイプのクエリはキャッシュなしで実行されます。
+ IN/EXISTS/ANY/ALL の相関サブクエリ
+ 非決定的関数を含む相関サブクエリ 
+ ハッシュまたは等価演算をサポートしていないデータ型で外部テーブル列を参照する相関サブクエリ。

# アダプティブ結合を使用したクエリパフォーマンスの向上
<a name="user-apg-adaptive-join"></a>

## 概要
<a name="user-apg-adaptive-join-intro"></a>

アダプティブ結合は、Aurora PostgreSQL 17.4 のプレビュー機能であり、クエリパフォーマンスの向上に役立ちます。この機能はデフォルトで無効になっていますが、グローバルユーザー設定 (GUC) パラメータを使用して有効にできます。これはプレビュー機能であるため、デフォルトのパラメータ値は変更される場合があります。アダプティブ結合を有効にすると、ランタイム時にネストしたループ結合からハッシュ結合に動的に切り替えることで、クエリのパフォーマンスを最適化できます。この切り替えは、カーディナリティの見積りが不正確であるために、PostgreSQL オプティマイザがネストしたループ結合を誤って選択した場合に発生します。

## アダプティブ結合の設定
<a name="user-apg-adaptive-join-config"></a>

アダプティブ結合は、次の 3 つの GUC パラメータを使用して制御できます。


**アダプティブ結合の設定パラメータ**  

| GUC パラメータ | 説明 | デフォルトおよび設定オプション | 
| --- | --- | --- | 
| apg\$1adaptive\$1join\$1crossover\$1multiplier | この乗数は行のクロスオーバーポイントと連携して、ネストしたループ結合からハッシュ結合に切り替えるタイミングを決定します。行のクロスオーバーポイントは、ネストしたループ結合オペレーションとハッシュ結合オペレーションのコストが同じであると、SQL オプティマイザが推定した場所です。乗数の値を大きくすると、アダプティブ結合がハッシュ結合に切り替わる可能性が低くなります。 |  アダプティブ結合を有効にするかどうかを制御します [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/user-apg-adaptive-join.html)  | 
| apg\$1adaptive\$1join\$1cost\$1threshold | このパラメータは、クエリコストの最小しきい値を設定します。このしきい値を下回るクエリでは、アダプティブ結合が自動的に無効になります。これにより、アダプティブ結合を計画するコストが、ネストしたループ結合からハッシュ結合に切り替える利点を超えるような単純なクエリのパフォーマンスオーバーヘッドを回避できます。 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/user-apg-adaptive-join.html)  | 
| apg\$1enable\$1parameterized\$1adaptive\$1join | このパラメータは、有効になっている場合、アダプティブ結合機能をパラメータ化されたネストループ結合に拡張します。デフォルトでは、アダプティブ結合はパラメータ化されていないネストループ結合でのみ機能します。これは、ハッシュ結合に切り替えてメリットが得られる可能性が高いためです。パラメータ化されたネストループ結合は、通常、パフォーマンスが優れているため、ハッシュ結合への切り替えはそれほど重要ではありません。 |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/user-apg-adaptive-join.html) 最初に `apg_adaptive_join_crossover_multiplier` を有効にする必要があります  | 

# 共有プランキャッシュの使用
<a name="apg-shared-plan-cache"></a>

## 概要
<a name="apg-shared-plan-cache-overview"></a>

Aurora PostgreSQL は、各クライアント接続ごとに専用のバックエンドプロセスを作成する、ユーザーごとのプロセスモデルを使用します。各バックエンドプロセスでは、プリペアドステートメント用に独自のローカルプランキャッシュが維持されます。これらのキャッシュはプロセス間で共有できないため、多くのプリペアドステートメントを使用するアプリケーションでは、異なるバックエンドプロセス間で重複したキャッシュが作成され、メモリ使用量が増加する可能性があります。

Aurora PostgreSQL バージョン 17.6 以降および 16.10 以降では、共有プランキャッシュ機能が導入されています。この機能を有効にすると、バックエンドプロセスで汎用プランを共有できるため、重複したプラン生成を排除することでメモリ使用量が削減され、パフォーマンスが向上します。

共有プランキャッシュは、キャッシュキーとして次のコンポーネントを使用します。
+ クエリ文字列 (コメントを含む)
+ プランナー関連の GUC パラメータ (`search_path` を含む)
+ ユーザー ID
+ データベース ID

インスタンスの再起動により、共有キャッシュがリセットされます。

## パラメータ
<a name="apg-shared-plan-cache-parameters"></a>

次の表に、共有プランキャッシュ機能を制御するパラメータを示します。


| パラメータ | 説明 | デフォルト | 許可 | 
| --- | --- | --- | --- | 
| apg\$1shared\$1plan\$1cache.enable | 共有プランキャッシュのオン/オフを切り替える | 0 (オフ) | 0、1 | 
| apg\$1shared\$1plan\$1cache.max | キャッシュエントリの最大数 | 200～1,000 (インスタンスサイズによって異なります) | 100–50000 | 
| apg\$1shared\$1plan\$1cache.min\$1size\$1per\$1entry | 共有キャッシュに保存する最小プランサイズ。小規模なプランでは、ローカルキャッシュを使用して OLTP パフォーマンスを最適化します。 | 16 KB | 0～32,768 (KB) | 
| apg\$1shared\$1plan\$1cache.max\$1size\$1per\$1entry | 共有キャッシュの最大プランサイズ。より大きなプランではコスト情報のみが保存されます。 | 256 KB～4 MB (インスタンスサイズによって異なります) | 0～32,768 (KB) | 
| apg\$1shared\$1plan\$1cache.idle\$1generic\$1plan\$1release\$1timeout | アイドルセッションがローカル汎用プランをリリースするまでの時間。値を小さくするとメモリを節約でき、値を大きくするとパフォーマンスが向上する可能性があります。 | 10 秒 | 0～2,147,483,647 (ミリ秒) | 

**注記**  
再起動せずにすべてのパラメータを変更できます。

## ビューと関数のモニタリング
<a name="apg-shared-plan-cache-monitoring"></a>
+ `apg_shared_plan_cache()` – 詳細なキャッシュエントリ情報 (ヒット、有効性、タイムスタンプ) を表示します
+ `apg_shared_plan_cache_stat()` – インスタンスレベルの統計情報 (エビクション、無効化) を表示します
+ `apg_shared_plan_cache_reset()` – `apg_shared_plan_cache()` および `apg_shared_plan_cache_stat()` のすべてのエントリを削除します
+ `apg_shared_plan_cache_remove(cache_key)` – `apg_shared_plan_cache()` から、`cache_key` に一致するエントリを削除します

## 制限
<a name="apg-shared-plan-cache-limitations"></a>
+ プリペアドステートメントでのみ動作し、PL/pgSQL ステートメントはキャッシュされません
+ 一時テーブルまたはカタログテーブルを含むクエリをキャッシュしません
+ RLS (行レベルのセキュリティ) に依存するクエリをキャッシュしません
+ 各レプリカは独自のキャッシュを保持します (レプリカ間の共有はありません)