

# Uso de EXPLAIN y EXPLAIN ANALYZE en Athena
<a name="athena-explain-statement"></a>

La instrucción `EXPLAIN` muestra el plan de ejecución lógico o distribuido de una instrucción SQL especificada, o valida la instrucción SQL. Puede generar los resultados en formato de texto o en formato de datos para representarlos en un gráfico.

**nota**  
Puede ver representaciones gráficas de planes lógicos y distribuidos para sus consultas en la consola de Athena sin usar la sintaxis `EXPLAIN`. Para obtener más información, consulte [Visualización de planes de ejecución para consultas SQL](query-plans.md).

La instrucción `EXPLAIN ANALYZE` muestra el plan de ejecución distribuido de una instrucción SQL especificada y el costo computacional de cada operación en una consulta SQL. Puede generar los resultados en formato de texto o JSON. 

## Consideraciones y limitaciones
<a name="athena-explain-statement-considerations-and-limitations"></a>

Las instrucciones `EXPLAIN` y `EXPLAIN ANALYZE` de Athena tienen las siguientes limitaciones.
+ Dado que las consultas `EXPLAIN` no escanean ningún dato, Athena no cobra por ellas. Sin embargo, como las consultas `EXPLAIN` realizan llamadas a AWS Glue para recuperar metadatos de la tabla, puede incurrir en cargos de Glue si las llamadas superan el [límite de nivel gratuito 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).
+ Como se ejecutan las consultas `EXPLAIN ANALYZE`, analizan datos, de modo que Athena cobra en función de los datos escaneados.
+ La información de filtrado de filas o celdas definida en Lake Formation y la información de estadísticas de consultas no se muestran en la salida de `EXPLAIN` y `EXPLAIN ANALYZE`.

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

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

La *opción* puede ser una de las siguientes:

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

Si no se especifica la opción `FORMAT`, la salida predeterminada es en formato `TEXT`. El tipo `IO` proporciona información sobre las tablas y esquemas que la consulta lee. 

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

Además de la salida incluida en `EXPLAIN`, la salida `EXPLAIN ANALYZE` también incluye estadísticas de tiempo de ejecución de la consulta especificada, como el uso de CPU, el número de filas de entrada y el número de filas de salida.

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

La *opción* puede ser una de las siguientes:

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

Si no se especifica la opción `FORMAT`, la salida predeterminada es en formato `TEXT`. Como todas las consultas para `EXPLAIN ANALYZE` son `DISTRIBUTED`, la opción `TYPE` no está disponible para `EXPLAIN ANALYZE`. 

La *instrucción* puede ser una de las siguientes:

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

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

Los siguientes ejemplos de `EXPLAIN` avanzan de los más sencillos a los más complejos.

### Ejemplo 1: uso de la instrucción EXPLAIN para mostrar un plan de consulta en formato de texto
<a name="athena-explain-statement-example-text-query-plan"></a>

En el siguiente ejemplo, `EXPLAIN` muestra el plan de ejecución de una consulta `SELECT` en registros de Elastic Load Balancing. El formato se establece de forma predeterminada en la salida de texto.

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

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

### Ejemplo 2: uso de EXPLAIN para la representación gráfica de un plan de consulta
<a name="athena-explain-statement-example-graph-a-query-plan"></a>

Puede utilizar la consola de Athena para representar de manera gráfica un plan de consultas. Ingrese una instrucción `SELECT` como la siguiente en el editor de consultas de Athena y, a continuación, elija **EXPLICAR**.

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

Se abrirá la página **Explain** (Explicar) del editor de consultas de Athena y se mostrára un plan distribuido y un plan lógico para la consulta. En el siguiente gráfico se muestra el plan lógico para el ejemplo.

![\[Gráfico del plan de consulta representado por el editor de consulta de Athena.\]](http://docs.aws.amazon.com/es_es/athena/latest/ug/images/athena-explain-statement-tpch.png)


**importante**  
Actualmente, es posible que algunos filtros de partición no estén visibles en el gráfico de árbol de operadores anidado, aunque Athena los aplique a la consulta. Para comprobar el efecto de dichos filtros, ejecute `EXPLAIN` o `EXPLAIN ANALYZE` en la consulta y observe los resultados.

Para obtener más información sobre cómo usar las características de representación gráfica de planes de consulta en la consola de Athena, consulte [Visualización de planes de ejecución para consultas SQL](query-plans.md).

### Ejemplo 3: uso de la instrucción EXPLAIN para comprobar la eliminación de particiones
<a name="athena-explain-statement-example-verify-partition-pruning"></a>

Cuando se utiliza un predicado de filtrado en una clave particionada para consultar una tabla particionada, el motor de consultas aplica el predicado a la clave particionada para reducir la cantidad de datos leídos.

En el siguiente ejemplo se utiliza una consulta `EXPLAIN` para verificar la poda de partición para una consulta `SELECT` en una tabla particionada. Primero, una instrucción `CREATE TABLE` crea la tabla `tpch100.orders_partitioned`. La tabla está particionada en la columna `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 tabla `tpch100.orders_partitioned` tiene varias particiones en `o_orderdate`, como se muestra en el comando `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 siguiente consulta `EXPLAIN` comprueba la poda de partición en la instrucción `SELECT` especificada.

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

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

El texto en negrita del resultado muestra que se aplicó el predicado `o_orderdate = '1995'` en `PARTITION_KEY`.

### Ejemplo 4: uso de una consulta EXPLAIN para comprobar el orden de unión y el tipo de unión
<a name="athena-explain-statement-example-check-join-order-and-type"></a>

La siguiente consulta `EXPLAIN` verifica el orden y el tipo de unión de la instrucción `SELECT`. Utilice una consulta como esta para examinar el uso de la memoria de consulta de modo que pueda reducir las posibilidades de obtener un error `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
```

#### Resultados
<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 consulta de ejemplo se optimizó en una combinación cruzada para obtener un mejor rendimiento. Los resultados muestran que `tpch100.orders` se distribuirá como el tipo de distribución `BROADCAST`. Esto implica que la tabla `tpch100.orders` se distribuirá a todos los nodos que realizan la operación de unión. El tipo de distribución `BROADCAST` requerirá que todos los resultados filtrados de la tabla `tpch100.orders` se ajusten en la memoria de cada nodo que realiza la operación de unión.

Sin embargo, la tabla `tpch100.customer` es más pequeña que `tpch100.orders`. Dado que `tpch100.customer` requiere menos memoria, puede reescribir la consulta en `BROADCAST tpch100.customer` en lugar de `tpch100.orders`. Esto reduce la posibilidad de que la consulta reciba el error `EXCEEDED_LOCAL_MEMORY_LIMIT`. Esta estrategia supone los siguientes puntos:
+ La `tpch100.customer.c_custkey` es única en la tabla `tpch100.customer`.
+ Existe una relación de asignación de uno a muchos entre `tpch100.customer` y `tpch100.orders`.

En el siguiente ejemplo, se muestra la consulta reescrita.

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

### Ejemplo 5: uso de una consulta EXPLAIN para eliminar predicados que no tengan efecto
<a name="athena-explain-statement-example-remove-unneeded-predicates"></a>

Puede utilizar una consulta `EXPLAIN` para verificar la eficacia de los predicados de filtrado. Puede utilizar los resultados para eliminar predicados que no tengan ningún efecto, como en el ejemplo a continuación.

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

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

El `filterPredicate` en los resultados muestra que el optimizador fusionó los tres predicados originales en dos predicados y cambió su orden de aplicación.

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

Como los resultados muestran que el predicado `AND c.c_custkey BETWEEN 1000 AND 2000` no tiene ningún efecto, puede eliminar este predicado sin cambiar los resultados de la consulta.

Para obtener información sobre los términos utilizados en los resultados de las consultas `EXPLAIN`, consulte [Descripción de los resultados de la instrucción EXPLAIN de Athena](athena-explain-statement-understanding.md).

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

En los siguientes ejemplos, se muestran consultas y salidas `EXPLAIN ANALYZE`.

### Ejemplo 1: uso de EXPLAIN ANALYZE para mostrar un plan de consulta y los costos computacionales en formato de texto
<a name="athena-explain-analyze-example-cflogs-text"></a>

En el siguiente ejemplo, `EXPLAIN ANALYZE` muestra el plan de ejecución y los costos computacionales de una consulta `SELECT` en los registros de CloudFront. El formato se establece de forma predeterminada en la salida de texto.

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

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

### Ejemplo  2: uso de EXPLAIN ANALYZE para mostrar un plan de consulta en formato JSON
<a name="athena-explain-analyze-example-cflogs-json"></a>

En el siguiente ejemplo, se muestra el plan de ejecución y los costos computacionales de una consulta `SELECT` en los registros de CloudFront. En el ejemplo se especifica JSON como formato de salida.

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

#### Resultados
<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": [] 
                }] 
            }] 
        } 
    }] 
}
```

## Recursos adicionales
<a name="athena-explain-statement-additional-resources"></a>

Para obtener información adicional, consulte los siguientes recursos.
+  [Descripción de los resultados de la instrucción EXPLAIN de Athena](athena-explain-statement-understanding.md)
+  [Visualización de planes de ejecución para consultas SQL](query-plans.md)
+  [Visualización de estadísticas y detalles de ejecución de consultas completadas](query-stats.md)
+ Documentación de Trino sobre [https://trino.io/docs/current/sql/explain.html](https://trino.io/docs/current/sql/explain.html)
+ Documentación de Trino sobre [https://trino.io/docs/current/sql/explain-analyze.html](https://trino.io/docs/current/sql/explain-analyze.html)
+  [Optimice el rendimiento de las consultas federadas con EXPLAIN y EXPLAIN ANALYZE en Amazon Athena](https://aws.amazon.com/blogs/big-data/optimize-federated-query-performance-using-explain-and-explain-analyze-in-amazon-athena/) en el *Blog de macrodatos de AWS*. 

[![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)


# Descripción de los resultados de la instrucción EXPLAIN de Athena
<a name="athena-explain-statement-understanding"></a>

Este tema proporciona una breve guía de los términos operativos utilizados en los resultados de instrucciones `EXPLAIN` en Athena.

## Tipos de salida de instrucciones EXPLAIN
<a name="athena-explain-statement-understanding-explain-plan-types"></a>

`EXPLAIN`Las salidas de instrucciones pueden ser de dos tipos:
+ **Plan lógico**: muestra el plan lógico que utiliza el motor SQL para ejecutar una instrucción. La sintaxis para esta opción es `EXPLAIN` o `EXPLAIN (TYPE LOGICAL)`.
+ **Plan distribuido**: muestra un plan de ejecución en un entorno distribuido. La salida muestra fragmentos, que son etapas de procesamiento. Cada fragmento de plan es procesado por uno o más nodos. Los datos se pueden intercambiar entre los nodos que procesan los fragmentos. La sintaxis para esta opción es `EXPLAIN (TYPE DISTRIBUTED)`.

  En la salida de un plan distribuido, los fragmentos (etapas de procesamiento) están indicados por un `Fragment` *número* [*fragment\$1type*], donde el *número* es un entero basado en cero y *fragment\$1type* especifica cómo los nodos ejecutan el fragmento. En la siguiente tabla se describen los tipos de fragmentos, que proporcionan información del diseño del intercambio de datos.  
**Tipos de fragmentos del plan distribuido**    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/athena/latest/ug/athena-explain-statement-understanding.html)

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

Los términos relacionados con el intercambio describen cómo se intercambian datos entre nodos de trabajo. Las transferencias pueden ser locales o remotas. 

**LocalExchange [*exchange\$1type*] **  
Transfiere datos de manera local dentro de los nodos de trabajo para diferentes etapas de una consulta. El valor de *exchange\$1type* puede ser uno de los tipos de intercambio lógicos o distribuidos, como se describe más adelante en esta sección.

**RemoteExchange [*exchange\$1type*] **  
Transfiere datos entre los nodos de trabajo para diferentes etapas de una consulta. El valor de *exchange\$1type* puede ser uno de los tipos de intercambio lógicos o distribuidos, como se describe más adelante en esta sección.

### Tipos de intercambio lógico
<a name="athena-explain-statement-understanding-exchange-types-logical"></a>

Los siguientes tipos de intercambio describen las acciones efectuadas durante la fase de intercambio de un plan lógico.
+ **`GATHER`** – un nodo de trabajo único recopila la salida de todos los demás nodos de trabajo. Por ejemplo, la última etapa de una consulta de selección reúne los resultados de todos los nodos y los escribe en Amazon S3.
+ **`REPARTITION`** – envía los datos de fila a un empleado específico según el esquema de partición necesario para aplicar al siguiente operador.
+ **`REPLICATE`** – copia los datos de fila en todos los empleados.

### Tipos de intercambio distribuido
<a name="athena-explain-statement-understanding-exchange-types-distributed"></a>

Los siguientes tipos de intercambio indican el diseño de los datos cuando se intercambian entre nodos en un plan distribuido.
+ **`HASH`** – el intercambio distribuye datos a varios destinos utilizando una función hash.
+ **`SINGLE`** – el intercambio distribuye los datos a un único destino.

## Análisis
<a name="athena-explain-statement-understanding-scanning"></a>

Los siguientes términos describen cómo se analizan los datos durante una consulta.

**TableScan **  
Analiza los datos de origen de una tabla desde Amazon S3 o un conector Apache Hive y aplica la poda de partición generada a partir del predicado del filtro.

**ScanFilter **  
Analiza los datos de origen de una tabla desde Amazon S3 o un conector Hive y aplica la poda de partición generada a partir del predicado del filtro y de predicados de filtro adicionales no aplicados a través de la poda de partición.

**ScanFilterProject **  
Primero, analiza los datos de origen de una tabla desde Amazon S3 o un conector Hive y aplica la poda de partición generada a partir del predicado del filtro y de predicados de filtro adicionales no aplicados a través de la poda de partición. A continuación, modifica el diseño de la memoria de los datos de salida en una nueva proyección para mejorar el rendimiento de etapas posteriores.

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

Une datos entre dos tablas. Las uniones se pueden clasificar por tipo de unión y por tipo de distribución.

### Tipos de combinación
<a name="athena-explain-statement-understanding-join-types"></a>

Los tipos de unión definen la manera en que se produce la operación de unión.

**CrossJoin**: produce el producto cartesiano de las dos tablas unidas.

**InnerJoin**: selecciona registros que tienen valores coincidentes en ambas tablas.

**LeftJoin**: selecciona todos los registros de la tabla izquierda y los registros coincidentes de la tabla derecha. Si no se produce ninguna coincidencia, el resultado en el lado derecho es NULL.

**Right Join**: selecciona todos los registros de la tabla derecha y los registros coincidentes de la tabla izquierda. Si no se produce ninguna coincidencia, el resultado en el lado izquierdo es NULL.

**FullJoin**: selecciona todos los registros en los que hay una coincidencia en los registros de la tabla izquierda o derecha. La tabla combinada contiene todos los registros de las tablas y rellena NULL para las coincidencias que faltan en ambos lados.

**nota**  
Por razones de rendimiento, el motor de consultas puede reescribir una consulta de unión en un tipo de unión diferente para producir los mismos resultados. Por ejemplo, una consulta de unión interna con predicado en una tabla se puede volver a escribir en una `CrossJoin`. Esto empuja el predicado a la fase de escaneo de la tabla para que se escaneen menos datos.

### Tipos de distribución de unión
<a name="athena-explain-statement-understanding-join-distribution-types"></a>

Los tipos de distribución definen la manera en que se intercambian los datos entre nodos de trabajo cuando se realiza la operación de unión.

**Particionada**: tanto la tabla izquierda como la derecha están particionadas en hash en todos los nodos de trabajo. La distribución particionada consume menos memoria en cada nodo. La distribución particionada puede ser mucho más lenta que las uniones replicadas. Las uniones particionadas son adecuadas cuando se unen dos tablas grandes.

**Replicada**: una tabla está particionada en hash en todos los nodos de trabajo y la otra tabla se replica en todos los nodos de trabajo para realizar la operación de unión. La distribución replicada puede ser mucho más rápida que las uniones particionadas, pero consume más memoria en cada nodo de trabajo. Si la tabla replicada es demasiado grande, el nodo de trabajo puede experimentar un error de memoria insuficiente. Las uniones replicadas son adecuadas cuando una de las tablas combinadas es pequeña.