

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.

# Utilisation de EXPLAIN et EXPLAIN ANALYZE sur Athena
<a name="athena-explain-statement"></a>

L'instruction `EXPLAIN` montre le plan d'exécution logique ou distribué d'une instruction SQL spécifiée, ou valide l'instruction SQL. Vous pouvez produire les résultats au format texte ou dans un format de données pour les intégrer dans un graphique.

**Note**  
Vous pouvez afficher des représentations graphiques des plans logiques et distribués pour vos requêtes dans la console Athena sans utiliser la syntaxe `EXPLAIN`. Pour de plus amples informations, veuillez consulter [Affichage des plans d’exécution des requêtes SQL](query-plans.md).

L'instruction `EXPLAIN ANALYZE` montre à la fois le plan d'exécution distribué d'une instruction SQL spécifiée et le coût de calcul de chaque opération dans une requête SQL. Vous pouvez afficher les résultats au format texte ou JSON. 

## Considérations et restrictions
<a name="athena-explain-statement-considerations-and-limitations"></a>

Les instructions `EXPLAIN` et `EXPLAIN ANALYZE` sur Athena ont les limitations suivantes.
+ Comme les requêtes `EXPLAIN` n'analysent pas de données, Athena ne les facture pas. Cependant, étant donné que les requêtes `EXPLAIN` effectuent des appels vers AWS Glue pour récupérer les métadonnées des tables, vous pouvez encourir des frais de la part de Glue si les appels dépassent la limite de l'[offre gratuite de Glue](https://aws.amazon.com/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Categories=categories%23analytics&all-free-tier.q=glue&all-free-tier.q_operator=AND).
+ Étant donné que les requêtes `EXPLAIN ANALYZE` sont exécutées, elles analysent les données et Athena facture la quantité de données analysées.
+ Les informations de filtrage des lignes ou des cellules définies dans Lake Formation et les informations sur les statistiques des requêtes n'apparaissent pas dans la sortie de `EXPLAIN` et `EXPLAIN ANALYZE`.

## Syntaxe EXPLAIN
<a name="athena-explain-statement-syntax-athena-engine-version-2"></a>

```
EXPLAIN [ ( option [, ...]) ] statement
```

*option*, les valeurs suivantes sont possibles :

```
FORMAT { TEXT | GRAPHVIZ | JSON }
TYPE { LOGICAL | DISTRIBUTED | VALIDATE | IO }
```

Si l'option `FORMAT` n'est pas spécifiée, la sortie se fait par défaut au format `TEXT`. Le type `IO` fournit des informations sur les tables et les schémas lus par la requête. 

## Syntaxe EXPLAIN ANALYZE
<a name="athena-explain-analyze-statement"></a>

En plus de la sortie incluse dans `EXPLAIN`, la sortie `EXPLAIN ANALYZE` comprend également des statistiques d'exécution pour la requête spécifiée, telles que l'utilisation du CPU, le nombre de lignes en entrée et le nombre de lignes en sortie.

```
EXPLAIN ANALYZE [ ( option [, ...]) ] statement
```

*option*, les valeurs suivantes sont possibles :

```
FORMAT { TEXT | JSON }
```

Si l'option `FORMAT` n'est pas spécifiée, la sortie se fait par défaut au format `TEXT`. Parce que toutes les requêtes pour `EXPLAIN ANALYZE` sont `DISTRIBUTED`, l'option `TYPE` n'est pas disponible pour `EXPLAIN ANALYZE`. 

*statement*, les valeurs suivantes sont possibles :

```
SELECT
CREATE TABLE AS SELECT
INSERT
UNLOAD
```

## Exemples EXPLAIN
<a name="athena-explain-statement-examples"></a>

Les exemples suivants pour `EXPLAIN` vont du plus simple au plus complexe.

### Exemple 1 : utilisation de l’instruction EXPLAIN pour afficher un plan de requête au format texte
<a name="athena-explain-statement-example-text-query-plan"></a>

Dans l'exemple suivant, `EXPLAIN` affiche le plan d'exécution d'une requête `SELECT` sur les journaux Elastic Load Balancing. Le format est défini par défaut sur la sortie de texte.

```
EXPLAIN 
SELECT 
   request_timestamp, 
   elb_name, 
   request_ip 
FROM sampledb.elb_logs;
```

#### Résultats
<a name="athena-explain-statement-example-text-query-plan-results"></a>

```
- Output[request_timestamp, elb_name, request_ip] => [[request_timestamp, elb_name, request_ip]]
    - RemoteExchange[GATHER] => [[request_timestamp, elb_name, request_ip]]
        - TableScan[awsdatacatalog:HiveTableHandle{schemaName=sampledb, tableName=elb_logs, 
analyzePartitionValues=Optional.empty}] => [[request_timestamp, elb_name, request_ip]]
                LAYOUT: sampledb.elb_logs
                request_ip := request_ip:string:2:REGULAR
                request_timestamp := request_timestamp:string:0:REGULAR
                elb_name := elb_name:string:1:REGULAR
```

### Exemple 2 : utilisation de EXPLAIN pour présenter un plan de requête sous forme de graphique
<a name="athena-explain-statement-example-graph-a-query-plan"></a>

Vous pouvez utiliser la console Athena pour représenter graphiquement un plan de requête pour vous. Saisissez une instruction `SELECT` comme la suivante dans l'éditeur de requêtes Athena, puis choisissez **EXPLAIN**.

```
SELECT 
      c.c_custkey,
      o.o_orderkey,
      o.o_orderstatus
   FROM tpch100.customer c 
   JOIN tpch100.orders o 
       ON c.c_custkey = o.o_custkey
```

La page **EXPLAIN** de l'éditeur de requêtes Athena s'ouvre et affiche un plan distribué et un plan logique pour la requête. Le graphique suivant montre le plan logique de l'exemple.

![\[Graphique du plan de requête rendu par l'éditeur de requête Athena.\]](http://docs.aws.amazon.com/fr_fr/athena/latest/ug/images/athena-explain-statement-tpch.png)


**Important**  
Actuellement, certains filtres de partition peuvent ne pas être visibles dans l'arborescence des opérateurs imbriqués même si Athena les applique à votre requête. Pour vérifier l'effet de tels filtres, exécutez `EXPLAIN` ou `EXPLAIN ANALYZE` sur votre requête et affichez les résultats.

Pour plus d'informations sur l'utilisation des fonctionnalités de graphique du plan de requête dans la console Athena, consultez [Affichage des plans d’exécution des requêtes SQL](query-plans.md).

### Exemple 3 : utilisation de l’instruction EXPLAIN pour vérifier l’élagage des partitions
<a name="athena-explain-statement-example-verify-partition-pruning"></a>

Lorsque vous utilisez un prédicat de filtrage sur une clé partitionnée pour effectuer une requête sur une table partitionnée, le moteur de requête applique le prédicat à la clé partitionnée afin de réduire la quantité de données lues.

L'exemple suivant utilise une requête `EXPLAIN` pour vérifier l'élagage des partitions pour une requête `SELECT` sur une table partitionnée. Tout d'abord, une instruction `CREATE TABLE` crée la table `tpch100.orders_partitioned`. La table est partitionnée sur la colonne `o_orderdate`.

```
CREATE TABLE `tpch100.orders_partitioned`(
  `o_orderkey` int, 
  `o_custkey` int, 
  `o_orderstatus` string, 
  `o_totalprice` double, 
  `o_orderpriority` string, 
  `o_clerk` string, 
  `o_shippriority` int, 
  `o_comment` string)
PARTITIONED BY ( 
  `o_orderdate` string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://amzn-s3-demo-bucket/<your_directory_path>/'
```

La table `tpch100.orders_partitioned` a plusieurs partitions sur `o_orderdate`, comme le montre la commande `SHOW PARTITIONS`.

```
SHOW PARTITIONS tpch100.orders_partitioned;

o_orderdate=1994
o_orderdate=2015
o_orderdate=1998
o_orderdate=1995
o_orderdate=1993
o_orderdate=1997
o_orderdate=1992
o_orderdate=1996
```

La requête `EXPLAIN` suivante vérifie l'élagage des partitions sur l'instruction `SELECT` spécifiée.

```
EXPLAIN 
SELECT 
   o_orderkey, 
   o_custkey, 
   o_orderdate 
FROM tpch100.orders_partitioned
WHERE o_orderdate = '1995'
```

#### Résultats
<a name="athena-explain-statement-example-verify-partition-pruning-results"></a>

```
Query Plan
- Output[o_orderkey, o_custkey, o_orderdate] => [[o_orderkey, o_custkey, o_orderdate]]
    - RemoteExchange[GATHER] => [[o_orderkey, o_custkey, o_orderdate]]
        - TableScan[awsdatacatalog:HiveTableHandle{schemaName=tpch100, tableName=orders_partitioned, 
analyzePartitionValues=Optional.empty}] => [[o_orderkey, o_custkey, o_orderdate]]
                LAYOUT: tpch100.orders_partitioned
                o_orderdate := o_orderdate:string:-1:PARTITION_KEY
                    :: [[1995]]
                o_custkey := o_custkey:int:1:REGULAR
                o_orderkey := o_orderkey:int:0:REGULAR
```

Le texte en gras dans le résultat montre que le prédicat `o_orderdate = '1995'` a été appliqué sur la `PARTITION_KEY`.

### Exemple 4 : utilisation d’une requête EXPLAIN pour vérifier l’ordre et le type de jointure
<a name="athena-explain-statement-example-check-join-order-and-type"></a>

La requête `EXPLAIN` suivante vérifie l'ordre et le type de jointure de l'instruction `SELECT`. Utilisez une requête comme celle-ci pour examiner l'utilisation de la mémoire de la requête afin de réduire les risques d'erreur `EXCEEDED_LOCAL_MEMORY_LIMIT`.

```
EXPLAIN (TYPE DISTRIBUTED)
   SELECT 
      c.c_custkey, 
      o.o_orderkey,
      o.o_orderstatus
   FROM tpch100.customer c 
   JOIN tpch100.orders o 
       ON c.c_custkey = o.o_custkey 
   WHERE c.c_custkey = 123
```

#### Résultats
<a name="athena-explain-statement-example-check-join-order-and-type-results"></a>

```
Query Plan
Fragment 0 [SINGLE]
    Output layout: [c_custkey, o_orderkey, o_orderstatus]
    Output partitioning: SINGLE []
    Stage Execution Strategy: UNGROUPED_EXECUTION
    - Output[c_custkey, o_orderkey, o_orderstatus] => [[c_custkey, o_orderkey, o_orderstatus]]
        - RemoteSource[1] => [[c_custkey, o_orderstatus, o_orderkey]]

Fragment 1 [SOURCE]
    Output layout: [c_custkey, o_orderstatus, o_orderkey]
    Output partitioning: SINGLE []
    Stage Execution Strategy: UNGROUPED_EXECUTION
    - CrossJoin => [[c_custkey, o_orderstatus, o_orderkey]]
            Distribution: REPLICATED
        - ScanFilter[table = awsdatacatalog:HiveTableHandle{schemaName=tpch100, 
tableName=customer, analyzePartitionValues=Optional.empty}, grouped = false, 
filterPredicate = ("c_custkey" = 123)] => [[c_custkey]]
                LAYOUT: tpch100.customer
                c_custkey := c_custkey:int:0:REGULAR
        - LocalExchange[SINGLE] () => [[o_orderstatus, o_orderkey]]
            - RemoteSource[2] => [[o_orderstatus, o_orderkey]]

Fragment 2 [SOURCE]
    Output layout: [o_orderstatus, o_orderkey]
    Output partitioning: BROADCAST []
    Stage Execution Strategy: UNGROUPED_EXECUTION
    - ScanFilterProject[table = awsdatacatalog:HiveTableHandle{schemaName=tpch100, 
tableName=orders, analyzePartitionValues=Optional.empty}, grouped = false, 
filterPredicate = ("o_custkey" = 123)] => [[o_orderstatus, o_orderkey]]
            LAYOUT: tpch100.orders
            o_orderstatus := o_orderstatus:string:2:REGULAR
            o_custkey := o_custkey:int:1:REGULAR
            o_orderkey := o_orderkey:int:0:REGULAR
```

La requête donnée en exemple a été optimisée en une jointure croisée pour une meilleure performance. Les résultats montrent que `tpch100.orders` sera distribué comme le type de distribution `BROADCAST`. Cela implique que la table `tpch100.orders` sera distribuée à tous les nœuds qui effectuent l'opération de jointure. Le type de distribution `BROADCAST` exigera que tous les résultats filtrés de la table `tpch100.orders` tiennent dans la mémoire de chaque nœud qui effectue l'opération de jointure.

Cependant, la table `tpch100.customer` est plus petite que `tpch100.orders`. Comme `tpch100.customer` nécessite moins de mémoire, vous pouvez réécrire la requête en `BROADCAST tpch100.customer` au lieu de `tpch100.orders`. Cela réduit le risque que la requête reçoive une erreur `EXCEEDED_LOCAL_MEMORY_LIMIT`. Cette politique suppose les points suivants :
+ La `tpch100.customer.c_custkey` est unique dans la table `tpch100.customer`.
+ Il existe une relation one-to-many cartographique entre `tpch100.customer` et`tpch100.orders`.

L'exemple suivant illustre la requête réécrite.

```
SELECT 
    c.c_custkey,
    o.o_orderkey,
    o.o_orderstatus
FROM tpch100.orders o
JOIN tpch100.customer c -- the filtered results of tpch100.customer are distributed to all nodes.
    ON c.c_custkey = o.o_custkey 
WHERE c.c_custkey = 123
```

### Exemple 5 : utilisation d’une requête EXPLAIN pour supprimer les prédicats qui n’ont aucun effet
<a name="athena-explain-statement-example-remove-unneeded-predicates"></a>

Vous pouvez utiliser une requête `EXPLAIN` pour vérifier l'efficacité du filtrage des prédicats. Vous pouvez utiliser les résultats pour supprimer les prédicats qui n'ont aucun effet, comme dans l'exemple suivant.

```
EXPLAIN
   SELECT 
      c.c_name
   FROM tpch100.customer c
   WHERE c.c_custkey = CAST(RANDOM() * 1000 AS INT)
   AND c.c_custkey BETWEEN 1000 AND 2000
   AND c.c_custkey = 1500
```

#### Résultats
<a name="athena-explain-statement-example-remove-unneeded-predicates-results"></a>

```
Query Plan
- Output[c_name] => [[c_name]]
    - RemoteExchange[GATHER] => [[c_name]]
        - ScanFilterProject[table = 
awsdatacatalog:HiveTableHandle{schemaName=tpch100, 
tableName=customer, analyzePartitionValues=Optional.empty}, 
filterPredicate = (("c_custkey" = 1500) AND ("c_custkey" = 
CAST(("random"() * 1E3) AS int)))] => [[c_name]]
                LAYOUT: tpch100.customer
                c_custkey := c_custkey:int:0:REGULAR
                c_name := c_name:string:1:REGULAR
```

Le `filterPredicate` dans les résultats montre que l'optimiseur a fusionné les trois prédicats d'origine en deux prédicats et a changé leur ordre d'application.

```
filterPredicate = (("c_custkey" = 1500) AND ("c_custkey" = CAST(("random"() * 1E3) AS int)))
```

Comme les résultats montrent que le prédicat `AND c.c_custkey BETWEEN 1000 AND 2000` n'a aucun effet, vous pouvez supprimer ce prédicat sans modifier les résultats de la requête.

Pour plus d'informations sur les termes utilisés dans les résultats des requêtes `EXPLAIN`, voir [Présentation des résultats de l’instruction EXPLAIN d’Athena](athena-explain-statement-understanding.md).

## Exemples EXPLAIN ANALYZE
<a name="athena-explain-analyze-examples"></a>

Les exemples suivants montrent des exemples de requêtes et de sorties `EXPLAIN ANALYZE`.

### Exemple 1 : utilisation de EXPLAIN ANALYZE pour afficher un plan de requête et un coût de calcul au format texte
<a name="athena-explain-analyze-example-cflogs-text"></a>

L'exemple suivant `EXPLAIN ANALYZE` montre le plan d'exécution et les coûts de calcul d'une `SELECT` requête sur les CloudFront journaux. Le format est défini par défaut sur la sortie de texte.

```
EXPLAIN ANALYZE SELECT FROM cloudfront_logs LIMIT 10
```

#### Résultats
<a name="athena-explain-analyze-example-cflogs-text-results"></a>

```
 Fragment 1
     CPU: 24.60ms, Input: 10 rows (1.48kB); per task: std.dev.: 0.00, Output: 10 rows (1.48kB)
     Output layout: [date, time, location, bytes, requestip, method, host, uri, status, referrer,\
       os, browser, browserversion]
Limit[10] => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
  browser, browserversion]]
             CPU: 1.00ms (0.03%), Output: 10 rows (1.48kB)
             Input avg.: 10.00 rows, Input std.dev.: 0.00%
LocalExchange[SINGLE] () => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
 browser, browserversion]]
                 CPU: 0.00ns (0.00%), Output: 10 rows (1.48kB)
                 Input avg.: 0.63 rows, Input std.dev.: 387.30%
RemoteSource[2] => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
  browser, browserversion]]
                     CPU: 1.00ms (0.03%), Output: 10 rows (1.48kB)
                     Input avg.: 0.63 rows, Input std.dev.: 387.30%

 Fragment 2
     CPU: 3.83s, Input: 998 rows (147.21kB); per task: std.dev.: 0.00, Output: 20 rows (2.95kB)
     Output layout: [date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
       browser, browserversion]
LimitPartial[10] => [[date, time, location, bytes, requestip, method, host, uri, status, referrer, os,\
  browser, browserversion]]
             CPU: 5.00ms (0.13%), Output: 20 rows (2.95kB)
             Input avg.: 166.33 rows, Input std.dev.: 141.42%
TableScan[awsdatacatalog:HiveTableHandle{schemaName=default, tableName=cloudfront_logs,\
  analyzePartitionValues=Optional.empty}, 
grouped = false] => [[date, time, location, bytes, requestip, method, host, uri, st
                 CPU: 3.82s (99.82%), Output: 998 rows (147.21kB)
                 Input avg.: 166.33 rows, Input std.dev.: 141.42%
                 LAYOUT: default.cloudfront_logs
                 date := date:date:0:REGULAR
                 referrer := referrer:string:9:REGULAR
                 os := os:string:10:REGULAR
                 method := method:string:5:REGULAR
                 bytes := bytes:int:3:REGULAR
                 browser := browser:string:11:REGULAR
                 host := host:string:6:REGULAR
                 requestip := requestip:string:4:REGULAR
                 location := location:string:2:REGULAR
                 time := time:string:1:REGULAR
                 uri := uri:string:7:REGULAR
                 browserversion := browserversion:string:12:REGULAR
                 status := status:int:8:REGULAR
```

### Exemple 2 : utilisation de EXPLAIN ANALYZE pour afficher un plan de requête au format JSON
<a name="athena-explain-analyze-example-cflogs-json"></a>

L'exemple suivant montre le plan d'exécution et les coûts de calcul d'une `SELECT` requête sur les CloudFront journaux. L'exemple spécifie JSON comme format de sortie.

```
EXPLAIN ANALYZE (FORMAT JSON) SELECT * FROM cloudfront_logs LIMIT 10
```

#### Résultats
<a name="athena-explain-analyze-example-cflogs-json-results"></a>

```
{ 
    "fragments": [{ 
        "id": "1", 
 
        "stageStats": { 
            "totalCpuTime": "3.31ms", 
            "inputRows": "10 rows", 
            "inputDataSize": "1514B", 
            "stdDevInputRows": "0.00", 
            "outputRows": "10 rows", 
            "outputDataSize": "1514B" 
        }, 
        "outputLayout": "date, time, location, bytes, requestip, method, host,\
           uri, status, referrer, os, browser, browserversion", 
 
        "logicalPlan": { 
            "1": [{ 
                "name": "Limit", 
                "identifier": "[10]", 
                "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host",\
                  "uri", "status", "referrer", "os", "browser", "browserversion"], 
                "details": "", 
                "distributedNodeStats": { 
                    "nodeCpuTime": "0.00ns", 
                    "nodeOutputRows": 10, 
                    "nodeOutputDataSize": "1514B", 
                    "operatorInputRowsStats": [{ 
                        "nodeInputRows": 10.0, 
                        "nodeInputRowsStdDev": 0.0 
                    }] 
                }, 
                "children": [{ 
                    "name": "LocalExchange", 
                    "identifier": "[SINGLE] ()", 
                    "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host",\
                      "uri", "status", "referrer", "os", "browser", "browserversion"], 
                    "details": "", 
                    "distributedNodeStats": { 
                        "nodeCpuTime": "0.00ns", 
                        "nodeOutputRows": 10, 
                        "nodeOutputDataSize": "1514B", 
                        "operatorInputRowsStats": [{ 
                            "nodeInputRows": 0.625, 
                            "nodeInputRowsStdDev": 387.2983346207417 
                        }] 
                    }, 
                    "children": [{ 
                        "name": "RemoteSource", 
                        "identifier": "[2]", 
                        "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host",\
                          "uri", "status", "referrer", "os", "browser", "browserversion"], 
                        "details": "", 
                        "distributedNodeStats": { 
                            "nodeCpuTime": "0.00ns", 
                            "nodeOutputRows": 10, 
                            "nodeOutputDataSize": "1514B", 
                            "operatorInputRowsStats": [{ 
                                "nodeInputRows": 0.625, 
                                "nodeInputRowsStdDev": 387.2983346207417 
                            }] 
                        }, 
                        "children": [] 
                    }] 
                }] 
            }] 
        } 
    }, { 
        "id": "2", 
 
        "stageStats": { 
            "totalCpuTime": "1.62s", 
            "inputRows": "500 rows", 
            "inputDataSize": "75564B", 
            "stdDevInputRows": "0.00", 
            "outputRows": "10 rows", 
            "outputDataSize": "1514B" 
        }, 
        "outputLayout": "date, time, location, bytes, requestip, method, host, uri, status,\
           referrer, os, browser, browserversion", 
 
        "logicalPlan": { 
            "1": [{ 
                "name": "LimitPartial", 
                "identifier": "[10]", 
                "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host", "uri",\
                  "status", "referrer", "os", "browser", "browserversion"], 
                "details": "", 
                "distributedNodeStats": { 
                    "nodeCpuTime": "0.00ns", 
                    "nodeOutputRows": 10, 
                    "nodeOutputDataSize": "1514B", 
                    "operatorInputRowsStats": [{ 
                        "nodeInputRows": 83.33333333333333, 
                        "nodeInputRowsStdDev": 223.60679774997897 
                    }] 
                }, 
                "children": [{ 
                    "name": "TableScan", 
                    "identifier": "[awsdatacatalog:HiveTableHandle{schemaName=default,\
                       tableName=cloudfront_logs, analyzePartitionValues=Optional.empty},\
                       grouped = false]", 
                    "outputs": ["date", "time", "location", "bytes", "requestip", "method", "host", "uri",\
                       "status", "referrer", "os", "browser", "browserversion"], 
                    "details": "LAYOUT: default.cloudfront_logs\ndate := date:date:0:REGULAR\nreferrer :=\
                       referrer: string:9:REGULAR\nos := os:string:10:REGULAR\nmethod := method:string:5:\
                       REGULAR\nbytes := bytes:int:3:REGULAR\nbrowser := browser:string:11:REGULAR\nhost :=\
                       host:string:6:REGULAR\nrequestip := requestip:string:4:REGULAR\nlocation :=\
                       location:string:2:REGULAR\ntime := time:string:1: REGULAR\nuri := uri:string:7:\
                       REGULAR\nbrowserversion := browserversion:string:12:REGULAR\nstatus :=\
                       status:int:8:REGULAR\n", 
                    "distributedNodeStats": { 
                        "nodeCpuTime": "1.62s", 
                        "nodeOutputRows": 500, 
                        "nodeOutputDataSize": "75564B", 
                        "operatorInputRowsStats": [{ 
                            "nodeInputRows": 83.33333333333333, 
                            "nodeInputRowsStdDev": 223.60679774997897 
                        }] 
                    }, 
                    "children": [] 
                }] 
            }] 
        } 
    }] 
}
```

## Ressources supplémentaires
<a name="athena-explain-statement-additional-resources"></a>

Pour plus d'informations, consultez les ressources suivantes.
+  [Présentation des résultats de l’instruction EXPLAIN d’Athena](athena-explain-statement-understanding.md)
+  [Affichage des plans d’exécution des requêtes SQL](query-plans.md)
+  [Affichage des statistiques et des détails d’exécution des requêtes terminées](query-stats.md)
+ Documentation Trino [https://trino.io/docs/current/sql/explain.html](https://trino.io/docs/current/sql/explain.html)
+ Documentation Trino [https://trino.io/docs/current/sql/explain-analyze.html](https://trino.io/docs/current/sql/explain-analyze.html)
+  [Optimisez les performances des requêtes fédérées à l'aide d'EXPLAIN et EXPLAIN ANALYZE dans Amazon Athena](https://aws.amazon.com/blogs/big-data/optimize-federated-query-performance-using-explain-and-explain-analyze-in-amazon-athena/) sur le *blog AWS Big Data*. 

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/7JUyTqglmNU/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/7JUyTqglmNU)


# Présentation des résultats de l’instruction EXPLAIN d’Athena
<a name="athena-explain-statement-understanding"></a>

Cette rubrique fournit un bref guide des termes opérationnels utilisés dans les résultats des instructions `EXPLAIN` dans Athena.

## Types de sorties de l'instruction EXPLAIN
<a name="athena-explain-statement-understanding-explain-plan-types"></a>

Les sorties de l'instruction `EXPLAIN` peuvent être de deux types :
+ **Logical plan** (Plan logique) : affiche le plan logique utilisé par le moteur SQL pour exécuter une instruction. La syntaxe correspondante est `EXPLAIN` ou `EXPLAIN (TYPE LOGICAL)`.
+ **Distributed plan** (Plan distribué) : affiche un plan d'exécution dans un environnement distribué. La sortie montre les fragments, qui sont des étapes de traitement. Chaque fragment de plan est traité par un ou plusieurs nœuds. Les données peuvent être échangées entre les nœuds qui traitent les fragments. La syntaxe correspondante est `EXPLAIN (TYPE DISTRIBUTED)`.

  Dans la sortie d'un plan distribué, les fragments (étapes de traitement) sont indiqués par `Fragment` *number* [*fragment\$1type*], où *number* est un entier de base zéro et *fragment\$1type* indique comment le fragment est exécuté par les nœuds. Les types de fragments, qui donnent des informations sur la disposition de l'échange de données (Data Exchange), sont décrits dans le tableau suivant.  
**Types de fragments de plan distribué**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/athena/latest/ug/athena-explain-statement-understanding.html)

## Exchange
<a name="athena-explain-statement-understanding-exchange-types"></a>

Les termes liés à l'échange décrivent la façon dont les données sont échangées entre les composants master. Les transferts peuvent être locaux ou distants. 

**LocalExchange [*exchange\$1type*] **  
Transfère les données localement dans les composants master pour les différentes étapes d'une requête. La valeur pour *exchange\$1type* peut être l'un des types d'échange logiques ou distribués, comme décrit plus loin dans cette section.

**RemoteExchange [*exchange\$1type*] **  
Transfert de données entre les composants master pour les différentes étapes d'une requête. La valeur pour *exchange\$1type* peut être l'un des types d'échange logiques ou distribués, comme décrit plus loin dans cette section.

### Types d'échanges logiques
<a name="athena-explain-statement-understanding-exchange-types-logical"></a>

Les types d'échange suivants décrivent les actions prises pendant la phase d'échange d'un plan logique.
+ **`GATHER`** : un seul composant master rassemble la sortie de tous les autres composants master. Par exemple, la dernière étape d'une requête Select rassemble les résultats de tous les nœuds et écrit les résultats sur Simple Storage Service (Amazon S3).
+ **`REPARTITION`** : envoie les données de la ligne à un esclave spécifique en fonction du schéma de partitionnement requis pour s'appliquer à l'opérateur suivant.
+ **`REPLICATE`** : copie les données de ligne vers tous les esclaves.

### Types d'échanges distribués
<a name="athena-explain-statement-understanding-exchange-types-distributed"></a>

Les types d'échange suivants indiquent la disposition des données lorsqu'elles sont échangées entre les nœuds d'un plan distribué.
+ **`HASH`** : l'échange distribue des données vers plusieurs destinations à l'aide d'une fonction de hachage.
+ **`SINGLE`** : l'échange distribue les données vers une seule destination.

## Analyse
<a name="athena-explain-statement-understanding-scanning"></a>

Les conditions suivantes décrivent comment les données sont analysées au cours d'une requête.

**TableScan **  
Analyse les données source d'une table à partir de Simple Storage Service (Amazon S3) ou d'un connecteur Apache Hive et applique l'élagage des partitions généré par le prédicat du filtre.

**ScanFilter **  
Analyse les données source d'une table à partir de Simple Storage Service (Amazon S3) ou d'un connecteur Hive et applique l'élagage de partitions généré par le prédicat de filtre et par des prédicats de filtre supplémentaires non appliqués par l'élagage de partitions.

**ScanFilterProject **  
Tout d'abord, il analyse les données source d'une table à partir de Simple Storage Service (Amazon S3) ou d'un connecteur Hive et applique l'élagage de partitions généré par le prédicat de filtre et par des prédicats de filtre supplémentaires non appliqués par l'élagage de partitions. Ensuite, il modifie la disposition de la mémoire des données de sortie en une nouvelle projection afin d'améliorer les performances des étapes ultérieures.

## Joindre
<a name="athena-explain-statement-understanding-join"></a>

Joint les données entre deux tables. Les jointures peuvent être classées par type de jointure et par type de distribution.

### Types de jointures
<a name="athena-explain-statement-understanding-join-types"></a>

Les types de jointure définissent la manière dont l'opération de jointure se produit.

**CrossJoin**— Produit le produit cartésien des deux tables jointes.

**InnerJoin**— Sélectionne les enregistrements dont les valeurs correspondent dans les deux tables.

**LeftJoin**— Sélectionne tous les enregistrements de la table de gauche et les enregistrements correspondants de la table de droite. Si aucune correspondance ne se produit, le résultat sur le côté droit est NULL.

**RightJoin**— Sélectionne tous les enregistrements de la table de droite et les enregistrements correspondants de la table de gauche. Si aucune correspondance ne se produit, le résultat sur le côté gauche est NULL.

**FullJoin**— Sélectionne tous les enregistrements présentant une correspondance dans les enregistrements de la table de gauche ou de droite. La table jointe contient tous les enregistrements des deux tables et complète NULLs les correspondances manquantes de chaque côté.

**Note**  
Pour des raisons de performances, le moteur de requête peut réécrire une requête de jointure dans un type de jointure différent pour produire les mêmes résultats. Par exemple, une requête de jointure interne avec prédicat sur une table peut être réécrite dans un `CrossJoin`. Cela repousse le prédicat vers la phase de balayage de la table, de sorte que moins de données sont balayées.

### Types de distributions des jointures
<a name="athena-explain-statement-understanding-join-distribution-types"></a>

Les types de distribution définissent la façon dont les données sont échangées entre les composants master lorsque l'opération de jointure est exécutée.

**Partitionné** : les tables de gauche et de droite sont partitionnées par hachage sur tous les composants master. La distribution partitionnée consomme moins de mémoire dans chaque nœud. La distribution partitionnée peut être beaucoup plus lente que les jointures répliquées. Les jointures partitionnées conviennent lorsque vous joignez deux grandes tables.

**Répliqué** : une table est partitionnée par hachage sur tous les composants master et l'autre table est répliquée sur tous les composants master pour effectuer l'opération de jointure. La distribution répliquée peut être beaucoup plus rapide que les jointures partitionnées, mais elle consomme plus de mémoire dans chaque composant master. Si la table répliquée est trop grande, le nœud de travail peut rencontrer une out-of-memory erreur. Les jointures répliquées conviennent lorsque l'une des tables jointes est petite.