

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.

# Aurora DSQL EXPLAIN-Pläne lesen
<a name="reading-dsql-explain-plans"></a>

Zu verstehen, wie man EXPLAIN-Pläne liest, ist der Schlüssel zur Optimierung der Abfrageleistung. In diesem Abschnitt gehen wir reale Beispiele für Aurora DSQL-Abfragepläne durch, zeigen, wie sich verschiedene Scantypen verhalten, erklären, wo Filter angewendet werden, und zeigen Optimierungsmöglichkeiten auf.

## In diesen Beispielen verwendete Beispieltabellen
<a name="explain-plan-sample-tables"></a>

Die folgenden Beispiele verweisen auf zwei Tabellen: `transaction` und`account`.

Die `transaction` Tabelle hat keinen Primärschlüssel, weshalb Aurora DSQL bei der Abfrage vollständige Tabellenscans durchführt.

Für die `account` Tabelle ist ein Index aktiviert. `customer_id` Dieser Index beinhaltet `balance` und `status` als Deckspalten, sodass bestimmte Abfragen direkt vom Index aus beantwortet werden können, ohne aus der Basistabelle lesen zu müssen. Da der Index jedoch keine Daten enthält`created_at`, benötigen Abfragen, die auf diese Spalte verweisen, zusätzlichen Tabellenzugriff.

```
CREATE TABLE transaction (
    account_id uuid,
    transaction_date timestamp,
    description text
);

CREATE TABLE account (
    customer_id uuid,
    balance numeric,
    status varchar,
    created_at timestamp
);

CREATE INDEX ASYNC idx1 ON account (customer_id) INCLUDE (balance, status);
```

## Beispiel für einen vollständigen Scan
<a name="full-scan-example"></a>

Aurora DSQL verfügt sowohl über sequentielle Scans, die funktionell identisch mit PostgreSQL sind, als auch über vollständige Scans. Der einzige Unterschied zwischen diesen beiden besteht darin, dass bei vollständigen Scans zusätzliche Speicherfilterung verwendet werden kann. Aus diesem Grund wird diese Option fast immer über „Sequentielle Scans“ ausgewählt. Aufgrund der Ähnlichkeit werden wir nur Beispiele für die interessanteren vollständigen Scans behandeln.

Vollständige Scans werden hauptsächlich für Tabellen ohne Primärschlüssel verwendet. Da Aurora DSQL-Primärschlüssel standardmäßig Indizes vollständig abdecken, wird Aurora DSQL in vielen Situationen, in denen PostgreSQL einen sequentiellen Scan verwenden würde, höchstwahrscheinlich Index-Only-Scans für den Primärschlüssel verwenden. Wie bei den meisten anderen Datenbanken wird eine Tabelle ohne Indizes schlecht skaliert.

```
EXPLAIN SELECT account_id FROM transaction WHERE transaction_date > '2025-01-01' AND description LIKE '%external%';
```

```
                                                   QUERY PLAN
----------------------------------------------------------------------------------------------------------------
 Full Scan (btree-table) on transaction  (cost=125100.05..177933.38 rows=33333 width=16)
   Filter: (description ~~ '%external%'::text)
   -> Storage Scan on transaction (cost=12510.05..17793.38 rows=66666 width=16)
        Projections: account_id, description
        Filters: (transaction_date > '2025-01-01 00:00:00'::timestamp without time zone)
        -> B-Tree Scan on transaction (cost=12510.05..17793.38 rows=100000 width=30)
```

Dieser Plan zeigt zwei Filter, die in unterschiedlichen Phasen angewendet werden. Die `transaction_date > '2025-01-01'` Bedingung wird auf die Speicherebene angewendet, wodurch die Menge der zurückgegebenen Daten reduziert wird. Die `description LIKE '%external%'` Bedingung wird später im Abfrageprozessor angewendet, nachdem Daten übertragen wurden, wodurch sie weniger effizient ist. Das Verschieben selektiverer Filter in die Speicher- oder Indexebene verbessert im Allgemeinen die Leistung.

## Beispiel „Nur Index scannen“
<a name="index-only-scan-example"></a>

Nur Index-Scans sind die optimalsten Scantypen in Aurora DSQL, da sie zu den wenigsten Roundtrips zur Speicherebene führen und am meisten filtern können. Aber nur weil Sie Index Only Scan sehen, heißt das nicht, dass Sie den besten Plan haben. Aufgrund der unterschiedlichen Filterstufen, die auftreten können, ist es wichtig, trotzdem darauf zu achten, an welchen Stellen gefiltert werden kann.

```
EXPLAIN SELECT balance FROM account 
WHERE customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb' 
AND balance > 100 
AND status = 'pending';
```

```
                                  QUERY PLAN
-------------------------------------------------------------------------------
 Index Only Scan using idx1 on account  (cost=725.05..1025.08 rows=8 width=18)
   Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   Filter: (balance > '100'::numeric)
   -> Storage Scan on idx1 (cost=12510.05..17793.38 rows=9 width=16)
        Projections: balance
        Filters: ((status)::text = 'pending'::text)
        -> B-Tree Scan on idx1 (cost=12510.05..17793.38 rows=10 width=30)
            Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
```

In diesem Plan wird die Indexbedingung `customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'` () zuerst während des Indexscans ausgewertet. Dies ist die effizienteste Phase, da sie begrenzt, wie viele Daten aus dem Speicher gelesen werden. Der Speicherfilter,`status = 'pending'`, wird nach dem Lesen der Daten, aber bevor sie an die Rechenebene gesendet werden, angewendet, wodurch die übertragene Datenmenge reduziert wird. Schließlich wird der Filter für den Abfrageprozessor`balance > 100`,, zuletzt ausgeführt, nachdem die Daten verschoben wurden, was ihn am wenigsten effizient macht. Von diesen bietet die Indexbedingung die beste Leistung, da sie direkt steuert, wie viele Daten gescannt werden.

## Beispiel für einen Index-Scan
<a name="index-scan-example"></a>

Index-Scans ähneln Nur-Index-Scans, mit dem Unterschied, dass sie zusätzlich die Basistabelle aufrufen müssen. Da Aurora DSQL Speicherfilter angeben kann, ist dies sowohl beim Indexaufruf als auch beim Suchaufruf möglich.

Um dies zu verdeutlichen, präsentiert Aurora DSQL den Plan als zwei Knoten. Auf diese Weise können Sie deutlich erkennen, wie hilfreich das Hinzufügen einer Include-Spalte in Bezug auf die aus dem Speicher zurückgegebenen Zeilen ist.

```
EXPLAIN SELECT balance FROM account 
WHERE customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'
AND balance > 100 
AND status = 'pending' 
AND created_at > '2025-01-01';
```

```
                                                QUERY PLAN
----------------------------------------------------------------------------------------------------------
 Index Scan using idx1 on account  (cost=728.18..1132.20 rows=3 width=18)
   Filter: (balance > '100'::numeric)
   Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   -> Storage Scan on idx1 (cost=12510.05..17793.38 rows=8 width=16)
        Projections: balance
        Filters: ((status)::text = 'pending'::text)
        -> B-Tree Scan on account (cost=12510.05..17793.38 rows=10 width=30)
            Index Cond: (customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'::uuid)
   -> Storage Lookup on account (cost=12510.05..17793.38 rows=4 width=16)
        Filters: (created_at > '2025-01-01 00:00:00'::timestamp without time zone)
        -> B-Tree Lookup on transaction (cost=12510.05..17793.38 rows=8 width=30)
```

 Dieser Plan zeigt, wie die Filterung über mehrere Stufen hinweg erfolgt: 
+  Die Indexbedingung für `customer_id ` filtert Daten frühzeitig. 
+ Durch den eingeschalteten Speicherfilter werden die Ergebnisse `status` weiter eingegrenzt, bevor sie an die Datenverarbeitung gesendet werden. 
+ Der aktivierte Filter für den Abfrageprozessor `balance` wird später, nach der Übertragung, angewendet.
+ Der aktivierte Suchfilter `created_at` wird beim Abrufen zusätzlicher Spalten aus der Basistabelle ausgewertet. 

Durch das Hinzufügen häufig verwendeter Spalten als `INCLUDE` Felder kann diese Suche häufig vermieden und die Leistung verbessert werden. 

## Bewährte Methoden
<a name="best-practices"></a>
+ **Richten Sie die Filter an den indizierten Spalten aus**, um die Filterung früher voranzutreiben.
+ **Verwenden Sie INCLUDE-Spalten**, um reine Index-Scans zu ermöglichen und Suchvorgänge zu vermeiden.
+ **Überprüfen Sie die Zeilenschätzungen** bei der Untersuchung von Leistungsproblemen. Aurora DSQL verwaltet Statistiken automatisch, indem es `ANALYZE` im Hintergrund auf der Grundlage der Datenänderungsraten ausgeführt wird. Wenn Schätzungen ungenau erscheinen, können Sie sie `ANALYZE` manuell ausführen, um die Statistiken sofort zu aktualisieren.
+ **Vermeiden Sie nicht indizierte Abfragen** in großen Tabellen, um teure vollständige Scans zu vermeiden.