

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Lecture des plans Aurora SQL EXPLAIN
<a name="reading-dsql-explain-plans"></a>

Comprendre comment lire les plans EXPLAIN est essentiel pour optimiser les performances des requêtes. Dans cette section, nous allons passer en revue des exemples concrets de plans de requêtes SQL Aurora, montrer le comportement des différents types de scan, expliquer où les filtres sont appliqués et mettre en évidence les opportunités d'optimisation.

## Exemples de tableaux utilisés dans ces exemples
<a name="explain-plan-sample-tables"></a>

Les exemples ci-dessous font référence à deux tableaux : `transaction` et`account`.

La `transaction` table ne possède pas de clé primaire, ce qui oblige Aurora DSQL à effectuer des analyses complètes de la table lorsqu'elle l'interroge.

La `account` table contient un index activé`customer_id`. Cet index inclut `balance` et `status` en tant que colonnes de couverture, ce qui permet de répondre à certaines requêtes directement à partir de l'index sans avoir à lire dans la table de base. Toutefois, l'index n'inclut pas`created_at`, de sorte que les requêtes qui font référence à cette colonne nécessitent un accès supplémentaire à la table.

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

## Exemple de scan complet
<a name="full-scan-example"></a>

Aurora DSQL propose à la fois des scans séquentiels, qui sont fonctionnellement identiques à PostgreSQL, ainsi que des scans complets. La seule différence entre les deux est que les scans complets peuvent utiliser un filtrage supplémentaire sur le stockage. Pour cette raison, il est presque toujours sélectionné au-dessus des scans séquentiels. En raison de la similitude, nous ne couvrirons que des exemples des scans complets les plus intéressants.

Les scans complets seront principalement utilisés sur des tables sans clé primaire. Étant donné que les clés primaires Aurora DSQL sont par défaut des index de couverture complets, Aurora DSQL utilisera très probablement des scans d'index uniquement sur la clé primaire dans de nombreuses situations où PostgreSQL utiliserait un scan séquentiel. Comme c'est le cas pour la plupart des autres bases de données, une table dépourvue d'index risque d'être mal dimensionnée.

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

Ce plan montre deux filtres appliqués à différentes étapes. La `transaction_date > '2025-01-01'` condition est appliquée au niveau de la couche de stockage, ce qui réduit la quantité de données renvoyées. La `description LIKE '%external%'` condition est appliquée ultérieurement dans le processeur de requêtes, une fois les données transférées, ce qui le rend moins efficace. L'introduction de filtres plus sélectifs dans les couches de stockage ou d'index améliore généralement les performances.

## Exemple de scan avec index uniquement
<a name="index-only-scan-example"></a>

Les scans d'index uniquement sont les types de scan les plus optimaux dans Aurora DSQL, car ils permettent de réduire le nombre d'allers-retours vers la couche de stockage et sont ceux qui peuvent effectuer le plus de filtrage. Mais ce n'est pas parce que vous voyez Index Only Scan que vous avez le meilleur plan. En raison des différents niveaux de filtrage qui peuvent se produire, il est essentiel de toujours faire attention aux différents endroits où le filtrage peut se produire.

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

Dans ce plan, la condition de l'index `customer_id = '4b18a761-5870-4d7c-95ce-0a48eca3fceb'` () est d'abord évaluée lors de l'analyse de l'index, qui est l'étape la plus efficace car elle limite la quantité de données lues depuis le stockage. Le filtre de stockage est appliqué après la lecture des données`status = 'pending'`, mais avant leur envoi à la couche de calcul, ce qui réduit la quantité de données transférées. Enfin, le filtre du processeur de requêtes s'exécute en dernier, une fois les données déplacées, ce qui le rend le moins efficace. `balance > 100` Parmi celles-ci, la condition d'index fournit les meilleures performances car elle contrôle directement la quantité de données numérisées.

## Exemple de scan d'index
<a name="index-scan-example"></a>

Les scans d'index sont similaires aux scans d'index uniquement, sauf qu'ils comportent l'étape supplémentaire d'appel à la table de base. Comme Aurora DSQL peut spécifier des filtres de stockage, il est en mesure de le faire à la fois lors de l'appel d'index et lors de l'appel de recherche.

Pour que cela soit clair, Aurora DSQL présente le plan sous la forme de deux nœuds. De cette façon, vous pouvez clairement voir dans quelle mesure l'ajout d'une colonne d'inclusion sera utile en termes de lignes renvoyées par le stockage.

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

 Ce plan montre comment le filtrage s'effectue en plusieurs étapes : 
+  La condition d'index sur les `customer_id ` filtres permet de filtrer les données à un stade précoce. 
+ Le filtre de stockage permet de `status` restreindre davantage les résultats avant qu'ils ne soient envoyés au calcul. 
+ Le filtre du processeur de requêtes activé `balance` est appliqué ultérieurement, après le transfert.
+ Le filtre de recherche activé `created_at` est évalué lors de la récupération de colonnes supplémentaires dans la table de base. 

L'ajout de colonnes fréquemment utilisées en tant que `INCLUDE` champs permet souvent d'éliminer cette recherche et d'améliorer les performances. 

## Bonnes pratiques
<a name="best-practices"></a>
+ **Alignez les filtres sur les colonnes indexées** pour accélérer le filtrage.
+ **Utilisez les colonnes INCLUDE** pour autoriser les scans d'index uniquement et éviter les recherches.
+ **Validez les estimations de lignes** lorsque vous étudiez les problèmes de performances. Aurora DSQL gère automatiquement les statistiques `ANALYZE` en s'exécutant en arrière-plan en fonction des taux de modification des données. Si les estimations semblent inexactes, vous pouvez les exécuter `ANALYZE` manuellement pour actualiser immédiatement les statistiques.
+ **Évitez les requêtes non indexées** sur de grandes tables afin d'éviter des scans complets coûteux.