

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Unterstützung der Tabellenpartition
<a name="AuroraPostgreSQL.QPM.Partitiontable"></a>

Aurora PostgreSQL Query Plan Management (QPM) unterstützt die deklarative Tabellenpartitionierung in den folgenden Versionen:
+ 15.3 und höhere 15-Versionen
+ 14.8 und höhere 14-Versionen
+ 13.11 und höhere 13-Versionen

Weitere Informationen finden Sie unter [Table Partitioning](https://www.postgresql.org/docs/current/ddl-partitioning.html).

**Topics**
+ [Einrichten der Tabellenpartition](#AuroraPostgreSQL.QPM.Partitiontable.setup)
+ [Erfassen von Plänen für die Tabellenpartition](#AuroraPostgreSQL.QPM.Partitiontable.capture)
+ [Erzwingen eines Tabellenpartitionsplans](#AuroraPostgreSQL.QPM.Partitiontable.enforcement)
+ [Namenskonvention](#AuroraPostgreSQL.QPM.Partitiontable.naming.convention)

## Einrichten der Tabellenpartition
<a name="AuroraPostgreSQL.QPM.Partitiontable.setup"></a>

 Gehen Sie wie folgt vor, um die Tabellenpartition in Aurora PostgreSQL QPM einzurichten: 

1. Setzen Sie `apg_plan_mgmt.plan_hash_version` in der DB-Cluster-Parametergruppe auf 3 oder mehr.

1. Navigieren Sie zu einer Datenbank, die Query Plan Management verwendet und Einträge in der Ansicht `apg_plan_mgmt.dba_plans` aufweist.

1. Rufen Sie `apg_plan_mgmt.validate_plans('update_plan_hash')` auf, um den `plan_hash`-Wert in der Plantabelle zu aktualisieren.

1. Wiederholen Sie die Schritte 2 bis 3 für alle Datenbanken, für die Query Plan Management aktiviert ist und die Einträge in `apg_plan_mgmt.dba_plans` aufweisen.

Weitere Informationen zu diesen Parametern finden Sie unter [Parameterreferenz für Aurora-PostgreSQL-Abfrageplanverwaltung](AuroraPostgreSQL.Optimize.Parameters.md).

## Erfassen von Plänen für die Tabellenpartition
<a name="AuroraPostgreSQL.QPM.Partitiontable.capture"></a>

In QPM werden verschiedene Pläne durch ihren `plan_hash`-Wert unterschieden. Um die Änderungen am `plan_hash` zu verstehen, müssen Sie zunächst ähnliche Pläne verstehen.

Die Kombination von Zugriffsmethoden, Indexnamen ohne Ziffern und Partitionsnamen ohne Ziffern, die auf der Ebene des Append-Knotens gespeichert sind, muss konstant sein, damit die Pläne als identisch gelten. Die spezifischen Partitionen, auf die in den Plänen zugegriffen wird, sind nicht wichtig. Im folgenden Beispiel wird eine Tabelle `tbl_a` mit 4 Partitionen erstellt.

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

Die folgenden Pläne gelten als identisch, da unabhängig von der Anzahl der Partitionen, nach denen die Abfrage sucht, eine einzige Scanmethode zum Scannen von `tbl_a` verwendet wird.

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

Die folgenden 3 Pläne gelten ebenfalls als identisch, da auf der übergeordneten Ebene die Zugriffsmethoden, Indexnamen ohne Ziffern und Partitionsnamen ohne Ziffern `SeqScan tbl_a` und `IndexScan (i_idx) tbl_a` lauten.

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

Unabhängig von der unterschiedlichen Reihenfolge und Anzahl der Vorkommen in untergeordneten Partitionen sind die Zugriffsmethoden, Indexnamen ohne Ziffern und Partitionsnamen ohne Ziffern auf der übergeordneten Ebene für jeden der oben aufgeführten Pläne konstant. 

Die Pläne würden jedoch nicht als identisch gelten, wenn eine der folgenden Bedingungen erfüllt ist:
+ Es werden zusätzliche Zugriffsmethoden im Plan verwendet.

  ```
  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)
  ```
+ Eine der im Plan enthaltenen Zugriffsmethoden wird nicht mehr verwendet.

  ```
  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)
  ```
+ Der einer Indexmethode zugeordnete Index wird geändert.

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

## Erzwingen eines Tabellenpartitionsplans
<a name="AuroraPostgreSQL.QPM.Partitiontable.enforcement"></a>

Genehmigte Pläne für partitionierte Tabellen werden durch Positionskorrespondenz erzwungen. Die Pläne sind nicht spezifisch für die Partitionen und können für andere Partitionen als die in der ursprünglichen Abfrage referenzierten Pläne erzwungen werden. Pläne können auch für Abfragen erzwungen werden, die auf eine andere Anzahl von Partitionen als die ursprünglich genehmigte Gliederung zugreifen.

Beispiel: Die genehmigte Gliederung gilt für den folgenden Plan:

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

Dann kann dieser Plan auch für SQL-Abfragen erzwungen werden, die 2, 4 oder mehr Partitionen referenzieren. Die möglichen Pläne, die sich aus diesen Szenarien für den Zugriff auf 2 und 4 Partitionen ergeben könnten, sind folgende:

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

Betrachten Sie einen anderen genehmigten Plan mit unterschiedlichen Zugriffsmethoden für jede Partition:

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

In diesem Fall würde jeder Plan, der aus zwei Partitionen liest, nicht erzwungen werden. Solange nicht alle Kombinationen (Zugriffsmethode, Indexname) aus dem genehmigten Plan verwendet werden können, kann der Plan nicht erzwungen werden. Die folgenden Pläne haben beispielsweise unterschiedliche Plan-Hashes und der genehmigte Plan kann in diesen Fällen nicht erzwungen werden:

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

## Namenskonvention
<a name="AuroraPostgreSQL.QPM.Partitiontable.naming.convention"></a>

Damit QPM einen Plan mit deklarativ partitionierten Tabellen durchsetzen kann, müssen Sie bestimmte Benennungsregeln für übergeordnete Tabellen, Tabellenpartitionen und Indizes befolgen: 
+ **Namen von übergeordneten Tabellen** – Diese Namen müssen sich durch alphanumerische oder Sonderzeichen und nicht nur durch Ziffern unterscheiden. Beispielsweise sind tA, tB und tC zulässige Namen für separate übergeordnete Tabellen, t1, t2 und t3 hingegen nicht. 
+ **Namen einzelner Partitionstabellen** – Partitionen derselben übergeordneten Tabelle dürfen sich nur durch Ziffern voneinander unterscheiden. Zulässige Partitionsnamen von tA könnten beispielsweise tA1, tA2 oder t1A, t2A oder auch mehrere Ziffern sein.

  Alle anderen Unterschiede (Buchstaben, Sonderzeichen) garantieren das Erzwingen des Plans nicht. 
+ **Indexnamen** – Stellen Sie in der Hierarchie der Partitionstabellen sicher, dass alle Indizes eindeutige Namen haben. Das bedeutet, dass die nicht numerischen Teile der Namen unterschiedlich sein müssen. Wenn Sie beispielsweise eine partitionierte Tabelle namens `tA` mit einem Index namens `tA_col1_idx1` haben, können Sie keinen anderen Index namens `tA_col1_idx2` haben. Sie können jedoch einen Index namens `tA_a_col1_idx2` haben, da der nicht numerische Teil des Namens eindeutig ist. Diese Regel gilt für Indizes, die sowohl für die übergeordnete Tabelle als auch für einzelne Partitionstabellen erstellt wurden. 

 Wenn die oben genannten Namenskonventionen nicht eingehalten werden, kann dies dazu führen, dass die genehmigten Pläne nicht erzwungen werden. Das folgende Beispiel veranschaulicht ein fehlgeschlagenes Erzwingen: 

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

Auch wenn die beiden Pläne identisch erscheinen mögen, unterscheiden sich ihre `Plan Hash`-Werte aufgrund der Namen der untergeordneten Tabellen. Die Tabellennamen unterscheiden sich nach Alphazeichen und nicht nur nach Ziffern, was dazu führt, dass die Durchsetzung fehlschlägt.