

# Optimización del rendimiento de Athena
<a name="performance-tuning"></a>

En este tema se proporciona información general y sugerencias específicas para mejorar el rendimiento de las consultas de Athena y para solucionar los errores relacionados con los límites y el uso de recursos.

En términos generales, las optimizaciones se pueden agrupar en categorías de servicio, consulta y estructura de datos. Las decisiones que se toman por cada servicio, sobre cómo se escriben las consultas y cómo se estructuran los datos y las tablas pueden influir en el rendimiento.

**Topics**
+ [Optimización del uso de servicio](performance-tuning-service-level-considerations.md)
+ [Optimización de consultas](performance-tuning-query-optimization-techniques.md)
+ [Optimización de datos](performance-tuning-data-optimization-techniques.md)
+ [Uso de formatos de almacenamiento en columnas](columnar-storage.md)
+ [Uso de particiones y asignación de buckets](ctas-partitioning-and-bucketing.md)
+ [Partición de datos](partitions.md)
+ [Uso de proyección de particiones con Amazon Athena](partition-projection.md)
+ [Evitar la limitación de Amazon S3](performance-tuning-s3-throttling.md)
+ [Recursos adicionales de](performance-tuning-additional-resources.md)

# Optimización del uso de servicio
<a name="performance-tuning-service-level-considerations"></a>

Entre las consideraciones por servicio se incluyen la cantidad de cargas de trabajo que se ejecutan por cuenta, las cuotas de servicio no solo para Athena, sino también para todos los servicios, y pensar en cómo reducir los errores de “falta de recursos”.

**Topics**
+ [Cómo operar cargas de trabajo múltiples dentro de la misma cuenta](#performance-tuning-service-quotas)
+ [Reducción de los errores de “falta de recursos”](#performance-tuning-resource-limits)

## Cómo operar cargas de trabajo múltiples dentro de la misma cuenta
<a name="performance-tuning-service-quotas"></a>

Athena utiliza cuotas para limitar la simultaneidad de consultas y las tasas de solicitudes de API a nivel de cuenta. Superar estas cuotas puede provocar que se produzcan errores en las consultas durante su ejecución o en el momento de su envío. Para obtener más información acerca de estas cuotas, consulte [Service Quotas](service-limits.md). 

Si opera varias cargas de trabajo dentro de la misma cuenta de AWS, estas competirán por la misma cuota a nivel de cuenta. Por ejemplo, si una carga de trabajo sufre una ráfaga inesperada de consultas, es posible que otra carga de trabajo que se ejecute en la misma cuenta tenga un tiempo de espera elevado o, en el peor de los casos, que se produzcan errores en el envío de las consultas debido a la limitación.

Recomendamos utilizar CloudWatch para supervisar el uso del servicio mediante gráficos y paneles. También puede configurar alarmas de CloudWatch que avisen cuando su uso se acerque a la cuota del servicio para consultas simultáneas, con lo cual podrá tomar medidas antes de alcanzar los límites de la cuota. Para obtener más información, consulte [Supervisión de las métricas de uso de Athena con CloudWatch](monitoring-athena-usage-metrics.md).

Para controlar la simultaneidad de las consultas y aislar las cargas de trabajo dentro de la cuenta, utilice las reservas de capacidad. Las reservas de capacidad proporcionan capacidad dedicada para el procesamiento de consultas dentro de una sola cuenta. La capacidad se mide en unidades de procesamiento de datos (DPU) y se puede agregar o eliminar para aumentar o disminuir la simultaneidad de las consultas, respectivamente. Las reservas de capacidad permiten aislar las cargas de trabajo entre sí dentro de la cuenta. Esto se consigue al asignar capacidad a uno o más grupos de trabajo. Para obtener más información, consulte [Administración de la capacidad de procesamiento de consultas](capacity-management.md).

Aunque debería separar las cargas de trabajo no relacionadas en diferentes cuentas de AWS (como aislar el desarrollo de los entornos de producción), este enfoque no ofrece una forma escalable de aumentar la simultaneidad de las consultas. En su lugar, utilice las reservas de capacidad para administrar y escalar las necesidades de procesamiento de consultas dentro de una sola cuenta.

### Consideración de las cuotas en otros servicios
<a name="performance-tuning-quotas-in-other-services"></a>

Cuando Athena ejecuta una consulta, puede llamar a otros servicios que imponen cuotas. Durante la ejecución de la consulta, Athena puede realizar llamadas a la API de AWS Glue Data Catalog, Amazon S3 y otros servicios de AWS, como IAM y AWS KMS. Si se utilizan [consultas federadas](federated-queries.md), Athena también llama a AWS Lambda. Todos estos servicios tienen sus propios límites y cuotas que pueden superarse. Cuando la ejecución de una consulta detecta errores de estos servicios, se produce un error e incluye el error del servicio de origen. Los errores recuperables se vuelven a intentar, pero las consultas pueden seguir fallando si el problema no se resuelve a tiempo. Asegúrese de leer detenidamente los mensajes de error para determinar si provienen de Athena o de otro servicio. En esta sección de ajuste del rendimiento se describen algunos de los errores más pertinentes.

Para obtener más información sobre cómo solucionar los errores relacionados con las cuotas de servicio de Amazon S3, consulte [Cómo evitar tener demasiados archivos](performance-tuning-data-optimization-techniques.md#performance-tuning-avoid-having-too-many-files) más adelante en este documento. Para obtener más información sobre la optimización del rendimiento de Amazon S3, consulte [Prácticas recomendadas para patrones de diseño: optimizar el rendimiento de Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html) en la *Guía del usuario de Amazon S3*.

## Reducción de los errores de “falta de recursos”
<a name="performance-tuning-resource-limits"></a>

Athena ejecuta las consultas en un motor de consultas distribuido. Al enviar una consulta, el planificador de consultas del motor de Athena calcula la capacidad de procesamiento necesaria para ejecutar la consulta y prepara un clúster de nodos de computación en consecuencia. Algunas consultas, como las consultas DDL, se ejecutan en un solo nodo. Las consultas complejas sobre conjuntos de datos de gran tamaño se ejecutan en clústeres mucho más grandes. Los nodos son uniformes y tienen las mismas configuraciones de disco, CPU y memoria. Athena escala horizontalmente, no verticalmente, para procesar consultas más exigentes.

A veces, las demandas de una consulta superan los recursos disponibles para el clúster que ejecuta la consulta. Cuando esto ocurre, la consulta genera el error La consulta agotó los recursos con este factor de escala.

El recurso que se agota con más frecuencia es la memoria, pero en raras ocasiones también puede ser el espacio en disco. Los errores de memoria suelen producirse cuando el motor ejecuta una función de unión o ventana, pero también pueden producirse en distintos recuentos y agregaciones.

Aunque una consulta falle una vez y muestre el error de “falta de recursos”, es posible que se ejecute correctamente cuando se vuelva a ejecutar. La ejecución de la consulta no es determinista. Factores como el tiempo que se tarda en cargar los datos y la forma en que se distribuyen los conjuntos de datos intermedios en los nodos pueden provocar un uso diferente de los recursos. Imagine una consulta que une dos tablas y presenta un gran sesgo en la distribución de los valores de la condición de unión. Una consulta de este tipo puede funcionar correctamente la mayoría de las veces, pero en ocasiones falla cuando los valores más comunes terminan siendo procesados por el mismo nodo.

Para evitar que las consultas superen los recursos disponibles, utilice los consejos de ajuste de rendimiento que se mencionan en este documento. Para obtener consejos sobre cómo optimizar las consultas que agotan los recursos disponibles, consulte [Optimización de combinaciones](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-joins), [Reduzca el alcance de las funciones de la ventana o quítelas](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-window-functions) y [Optimización de las consultas mediante aproximaciones](performance-tuning-query-optimization-techniques.md#performance-tuning-optimizing-queries-by-using-approximations). 

# Optimización de consultas
<a name="performance-tuning-query-optimization-techniques"></a>

Utilice las técnicas de optimización de consultas que se describen en esta sección para hacer que las consultas se ejecuten más rápido o como soluciones para las consultas que superan los límites de recursos en Athena.

## Optimización de combinaciones
<a name="performance-tuning-optimizing-joins"></a>

Existen muchas estrategias diferentes para ejecutar uniones en un motor de consultas distribuido. Dos de las más comunes son las uniones hash distribuidas y las consultas con condiciones de unión complejas.

### En una combinación hash distribuida, coloque las tablas grandes a la izquierda y las pequeñas a la derecha
<a name="performance-tuning-distributed-hash-join"></a>

El tipo de unión más común utiliza una comparación de igualdad como condición de unión. Athena ejecuta este tipo de unión como una unión hash distribuida.

En una unión hash distribuida, el motor crea una tabla de consulta (tabla hash) a partir de uno de los lados de la unión. Este lado se denomina *lado de compilación*. Los registros del lado de compilación se distribuyen entre los nodos. Cada nodo crea una tabla de búsqueda para su subconjunto. El otro lado de la unión, denominado *lado de sondeo*, se transmite a través de los nodos. Los registros del lado de sondeo se distribuyen entre los nodos de la misma manera que en el lado de compilación. Esto permite que cada nodo realice la unión buscando los registros coincidentes en su propia tabla de búsqueda.

Cuando las tablas de búsqueda creadas a partir del lado de compilación de la unión no caben en la memoria, las consultas pueden fallar. Aun si el tamaño total del lado de compilación es inferior a la memoria disponible, las consultas pueden fallar si la distribución de los registros presenta un sesgo significativo. En un caso extremo, todos los registros podrían tener el mismo valor para la condición de unión y tener que caber en la memoria de un único nodo. Incluso una consulta con menos asimetría puede fallar si se envía un conjunto de valores al mismo nodo y los valores suman más que la memoria disponible. Los nodos tienen la capacidad de almacenar registros en el disco, pero esto ralentiza la ejecución de la consulta y puede que no sea suficiente para evitar que la consulta falle.

Athena intenta reordenar las uniones para usar la relación más grande como el lado de sondeo y la relación más pequeña como el lado de compilación. Sin embargo, como Athena no gestiona los datos de las tablas, tiene información limitada y, a menudo, debe suponer que la primera tabla es la más grande y la segunda es la más pequeña.

Al escribir uniones con condiciones de unión basadas en la igualdad, suponga que la tabla situada a la izquierda de la palabra clave `JOIN` corresponde al lado de sondeo y la tabla a la derecha corresponde al lado de compilación. Asegúrese de que la tabla correcta, la del lado de compilación, sea la más pequeña de las tablas. Si no es posible hacer que el lado de compilación de la unión sea lo suficientemente pequeño como para caber en la memoria, considere la posibilidad de ejecutar varias consultas que unan subconjuntos de la tabla de compilación.

### Utilice EXPLAIN para analizar consultas con combinaciones complejas
<a name="performance-tuning-other-join-types"></a>

Las consultas con condiciones de unión complejas (por ejemplo, las consultas que utilizan `LIKE`, `>` u otros operadores) suelen ser exigentes desde el punto de vista computacional. En el peor de los casos, todos los registros de un lado de la unión deben compararse con todos los registros del otro lado de la unión. Como el tiempo de ejecución aumenta con el cuadrado del número de registros, estas consultas corren el riesgo de superar el tiempo máximo de ejecución.

Para saber de antemano cómo Athena ejecutará su consulta, puede usar la instrucción `EXPLAIN`. Para obtener más información, consulte [Uso de EXPLAIN y EXPLAIN ANALYZE en Athena](athena-explain-statement.md) y [Descripción de los resultados de la instrucción EXPLAIN de Athena](athena-explain-statement-understanding.md).

## Reduzca el alcance de las funciones de la ventana o quítelas
<a name="performance-tuning-optimizing-window-functions"></a>

Como las funciones de ventana son operaciones que consumen muchos recursos, pueden hacer que las consultas se ejecuten con lentitud o incluso que se produzcan errores con el mensaje La consulta agotó los recursos con este factor de escala. Las funciones de ventana guardan en la memoria todos los registros en los que operan para calcular su resultado. Cuando la ventana es muy grande, la función de ventana puede quedarse sin memoria.

Para asegurarse de que las consultas se ejecuten dentro de los límites de memoria disponibles, reduzca el tamaño de las ventanas sobre las que trabajan las funciones de ventana. Para ello, puede agregar una cláusula `PARTITIONED BY` o reducir el alcance de las cláusulas de partición existentes.

### Uso de funciones que no sean de ventana
<a name="performance-tuning-optimizing-window-functions-rewrite"></a>

A veces, las consultas con funciones de ventana se pueden reescribir sin funciones de ventana. Por ejemplo, en lugar de utilizar `row_number` para buscar los registros de `N` principales, puede utilizar `ORDER BY` y `LIMIT`. En lugar de usar `row_number` o `rank` para desduplicar registros, puede usar funciones de agregado como [max\$1by](https://trino.io/docs/current/functions/aggregate.html#max_by), [min\$1by](https://trino.io/docs/current/functions/aggregate.html#min_by) y [arbitrary](https://trino.io/docs/current/functions/aggregate.html#arbitrary).

Por ejemplo, supongamos que tiene un conjunto de datos con actualizaciones de un sensor. El sensor informa periódicamente el estado de la batería e incluye algunos metadatos, como la ubicación. Si desea saber el último estado de la batería de cada sensor y su ubicación, puede usar la siguiente consulta:

```
SELECT sensor_id,
       arbitrary(location) AS location,
       max_by(battery_status, updated_at) AS battery_status
FROM sensor_readings
GROUP BY sensor_id
```

Los metadatos, como la ubicación, son los mismos para todos los registros, por lo que puede utilizar la función `arbitrary` a fin de seleccionar cualquier valor del grupo. 

Para obtener el último estado de la batería, puede usar la función `max_by`. La función `max_by` selecciona el valor de una columna del registro en el que se encontró el valor máximo de otra columna. En este caso, devuelve el estado de la batería del registro con la hora de la última actualización del grupo. Esta consulta se ejecuta más rápido y utiliza menos memoria que una consulta equivalente con una función de ventana. 

## Optimización de las agregaciones
<a name="performance-tuning-optimizing-aggregations"></a>

Cuando Athena realiza una agregación, distribuye los registros entre los nodos de trabajo mediante las columnas de la cláusula `GROUP BY`. Para que la tarea de hacer coincidir los registros con los grupos sea lo más eficiente posible, los nodos intentan mantener los registros en la memoria, pero los transfieren al disco si es necesario.

También es una buena idea evitar incluir columnas redundantes en las cláusulas `GROUP BY`. Dado que un menor número de columnas requiere menos memoria, resulta más eficaz una consulta que describa un grupo con menos columnas. Las columnas numéricas también utilizan menos memoria que las cadenas. Por ejemplo, al agregar un conjunto de datos que tiene un ID de categoría numérico y un nombre de categoría, utilice únicamente la columna de ID de categoría en la cláusula `GROUP BY`.

A veces, las consultas incluyen columnas en la cláusula `GROUP BY` para evitar el hecho de que una columna sea parte de la cláusula `GROUP BY` o una expresión agregada. Si no se sigue esta regla, puede producirse un error con el siguiente mensaje:

 EXPRESSION\$1NOT\$1AGGREGATE: line 1:8: 'category' must be an aggregate expression or appear in GROUP BY clause (EXPRESSION\$1NOT\$1AGGREGATE: línea 1:8: “categoría” debe ser una expresión agregada o aparecer en la cláusula GROUP BY). 

Para evitar tener que agregar columnas redundantes a la cláusula `GROUP BY`, puede utilizar la función [arbitrary](https://trino.io/docs/current/functions/aggregate.html#arbitrary), como en el siguiente ejemplo.

```
SELECT country_id,
       arbitrary(country_name) AS country_name,
       COUNT(*) AS city_count
FROM world_cities
GROUP BY country_id
```

La función `ARBITRARY` devuelve un valor arbitrario del grupo. La función resulta útil cuando se sabe que todos los registros del grupo tienen el mismo valor para una columna, pero el valor no identifica al grupo.

## Optimización de las N consultas principales
<a name="performance-tuning-optimizing-top-n-queries"></a>

La cláusula `ORDER BY` devuelve los resultados de una consulta ordenados. Athena usa la clasificación distribuida para ejecutar la operación de clasificación en paralelo en varios nodos.

Si no necesita estrictamente ordenar el resultado, evite agregar una cláusula `ORDER BY`. Además, evite agregar `ORDER BY` a las consultas internas si no son estrictamente necesarias. En muchos casos, el planificador de consultas puede eliminar la ordenación redundante, pero esto no está garantizado. Una excepción a esta regla es si una consulta interna está realizando una operación `N` principal, como buscar los valores `N` más recientes o los `N` más comunes.

Cuando Athena ve `ORDER BY` junto con `LIMIT`, entiende que se está ejecutando una consulta `N` principal y utiliza operaciones dedicadas en consecuencia.

**nota**  
Aunque Athena también suele detectar funciones de ventana como `row_number` que usan `N` principales, recomendamos la versión más sencilla que usa `ORDER BY` y `LIMIT`. Para obtener más información, consulte [Reduzca el alcance de las funciones de la ventana o quítelas](#performance-tuning-optimizing-window-functions).

## Inclusión de las columnas necesarias únicamente
<a name="performance-tuning-include-only-required-columns"></a>

Si no necesita estrictamente una columna, no la incluya en la consulta. Cuantos menos datos tenga que procesar una consulta, más rápido se ejecutará. Esto reduce tanto la cantidad de memoria necesaria como la cantidad de datos que deben enviarse entre los nodos. Si utiliza un formato de archivo en columnas, al reducir el número de columnas también se reduce la cantidad de datos que se leen desde Amazon S3.

Athena no tiene un límite específico para el número de columnas de un resultado, pero la forma en que se ejecutan las consultas limita el tamaño combinado de las columnas posible. El tamaño combinado de las columnas incluye los nombres y tipos.

Por ejemplo, el siguiente error se debe a una relación que supera el límite de tamaño de un descriptor de relación:

 GENERIC\$1INTERNAL\$1ERROR: io.airlift.bytecode.CompilationException 

Para solucionar este problema, reduzca el número de columnas de la consulta o cree subconsultas y utilice una cláusula `JOIN` que recupere una cantidad menor de datos. Si tiene consultas que aplican `SELECT *` en la consulta más externa, debe cambiar `*` a una lista de solo las columnas que necesita.

## Optimización de las consultas mediante aproximaciones
<a name="performance-tuning-optimizing-queries-by-using-approximations"></a>

Athena admite [funciones agregadas de aproximación](https://trino.io/docs/current/functions/aggregate.html#appro) para contar valores distintos, los valores más frecuentes, los percentiles (incluidas las medianas aproximadas) y crear histogramas. Utilice estas funciones siempre que no necesite valores exactos.

A diferencia de las operaciones `COUNT(DISTINCT col)`, [approx\$1distinct](https://trino.io/docs/current/functions/aggregate.html#approx_distinct) utiliza mucha menos memoria y se ejecuta más rápido. Del mismo modo, si se utiliza [numeric\$1histogram](https://trino.io/docs/current/functions/aggregate.html#numeric_histogram) en lugar de [histogram](https://trino.io/docs/current/functions/aggregate.html#histogram), se utilizan métodos aproximados y, por lo tanto, se utiliza menos memoria.

## Optimización de LIKE
<a name="performance-tuning-optimizing-like"></a>

Puede usar `LIKE` para encontrar cadenas coincidentes, pero con cadenas largas, esto requiere un uso intensivo de cómputos. La función [regexp\$1like](https://trino.io/docs/current/functions/regexp.html#regexp_like) es, en la mayoría de los casos, una alternativa más rápida que proporciona más flexibilidad.

A menudo, puede optimizar una búsqueda anclando la subcadena que está buscando. Por ejemplo, si busca un prefijo, es mucho mejor usar “*substr*%” en lugar de “%*substr*%”. O bien, si está usando `regexp_like`, “^*substr*”.

## Uso de UNION ALL en lugar de UNION
<a name="performance-tuning-use-union-all-instead-of-union"></a>

 `UNION ALL` y `UNION` son dos formas de combinar los resultados de dos consultas en un solo resultado. `UNION ALL` concatena los registros de la primera consulta con la segunda y `UNION` hace lo mismo, pero también elimina los duplicados. `UNION` necesita procesar todos los registros y encontrar los duplicados, lo que requiere mucha memoria y procesamiento, pero `UNION ALL` es una operación relativamente rápida. A menos que necesite desduplicar registros, use `UNION ALL` para obtener el mejor rendimiento.

## Uso de UNLOAD para conjuntos de resultados grandes
<a name="performance-tuning-use-unload-for-large-result-sets"></a>

Si se espera que los resultados de una consulta sean grandes (por ejemplo, decenas de miles de filas o más), utilice UNLOAD para exportar los resultados. En la mayoría de los casos, esto resulta más rápido que ejecutar una consulta normal y, además, usar `UNLOAD` permite tener más control sobre el resultado.

Cuando termina de ejecutarse una consulta, Athena almacena el resultado como un único archivo CSV sin comprimir en Amazon S3. Esto lleva más tiempo que `UNLOAD`, no solo porque el resultado no está comprimido, sino también porque la operación no se puede paralelizar. Por el contrario, `UNLOAD` escribe los resultados directamente desde los nodos de trabajo y aprovecha al máximo el paralelismo del clúster de computación. Además, puede configurar `UNLOAD` para escribir los resultados en formato comprimido y en otros formatos de archivo, como JSON y Parquet.

Para obtener más información, consulte [UNLOAD](unload.md). 

## Uso de CTAS o ETL de Glue para materializar las agregaciones de uso frecuente
<a name="performance-tuning-use-ctas-or-glue-etl-to-materialize-frequently-used-aggregations"></a>

La “materialización” de una consulta es una forma de acelerar el rendimiento de la consulta mediante el almacenamiento de resultados de consultas complejas precalculados (por ejemplo, agregaciones y uniones) para reutilizarlos en consultas posteriores.

Si varias de las consultas incluyen las mismas uniones y agregaciones, puede materializar la subconsulta común como una tabla nueva y, a continuación, ejecutar las consultas en esa tabla. Puede crear la nueva tabla con [Creación de una tabla a partir de los resultados de una consulta (CTAS)](ctas.md) o una herramienta ETL específica, como [ETL de Glue](https://aws.amazon.com/glue).

Por ejemplo, supongamos que tiene un panel con widgets que muestran diferentes aspectos de un conjunto de datos de pedidos. Cada widget tiene su propia consulta, pero todas las consultas comparten las mismas uniones y filtros. Una tabla de pedidos se une a una tabla de líneas de artículos y hay un filtro que muestra solo los últimos tres meses. Si se identifican las características comunes de estas consultas, se puede crear una tabla nueva que los widgets puedan usar. Esto reduce la duplicación y mejora el rendimiento. La desventaja es que se debe mantener la nueva tabla actualizada.

## Reutilización de resultados de las consultas
<a name="performance-tuning-reuse-query-results"></a>

Es habitual que la misma consulta se ejecute varias veces en poco tiempo. Por ejemplo, esto puede ocurrir cuando varias personas abren el mismo panel de datos. Al ejecutar una consulta, puede decirle a Athena que reutilice los resultados calculados con anterioridad. Usted especifica la antigüedad máxima de los resultados que se van a reutilizar. Si la misma consulta se ejecutó anteriormente dentro de ese periodo de tiempo, Athena devuelve esos resultados en lugar de volver a ejecutar la consulta. Para obtener más información, consulte [Reutilización de resultados de las consultas en Athena](reusing-query-results.md) en la *Guía del usuario de Amazon Athena* y [Reducir los costos y mejorar el rendimiento de las consultas con la reutilización de resultados de las consultas de Amazon Athena](https://aws.amazon.com/blogs/big-data/reduce-cost-and-improve-query-performance-with-amazon-athena-query-result-reuse/) en el *Blog de macrodatos de AWS*.

# Optimización de datos
<a name="performance-tuning-data-optimization-techniques"></a>

El rendimiento no solo depende de las consultas, sino también en gran medida de cómo esté organizado el conjunto de datos y del formato de archivo y de la compresión que utilice.

## Partición de datos
<a name="performance-tuning-partition-your-data"></a>

La creación de particiones divide la tabla en partes y mantiene los datos relacionados juntos de acuerdo con propiedades como la fecha, el país o la región. Las claves de partición actúan como columnas virtuales. Las claves de partición se definen al crear la tabla y se utilizan para filtrar las consultas. Al filtrar las columnas de claves de partición, solo se leen los datos de las particiones coincidentes. Por ejemplo, si el conjunto de datos está dividido por fecha y la consulta tiene un filtro que solo coincide con la última semana, solo se leerán los datos de la última semana. Para obtener más información sobre la creación de particiones, consulte [Partición de datos](partitions.md).

## Elección de claves de partición compatibles con las consultas
<a name="performance-tuning-pick-partition-keys-that-will-support-your-queries"></a>

Dado que la creación de particiones tiene un impacto significativo en el rendimiento de las consultas, asegúrese de considerar cuidadosamente cómo crear las particiones al diseñar el conjunto de datos y las tablas. Tener demasiadas claves de partición puede provocar conjuntos de datos fragmentados con demasiados archivos y archivos demasiado pequeños. Por el contrario, tener muy pocas claves de partición, o no tener ninguna partición, hace que las consultas analicen más datos de los necesarios.

### Cómo evitar optimizar consultas poco frecuentes
<a name="performance-tuning-avoid-optimizing-for-rare-queries"></a>

Una buena estrategia consiste en optimizar las consultas más comunes y evitar la optimización para las consultas poco frecuentes. Por ejemplo, si sus consultas están basadas en intervalos de días, no las divida por hora, incluso si algunas consultas se filtran a ese nivel. Si sus datos tienen una columna de marca de tiempo detallada, las consultas poco frecuentes que se filtran por hora pueden usar la columna de marca de tiempo. Incluso si en los casos poco frecuentes se analizan un poco más de datos de los necesarios, reducir el rendimiento general en aras de los casos excepcionales no suele ser una buena compensación.

Para reducir la cantidad de datos que se deben analizar en las consultas y, por lo tanto, mejorar el rendimiento, utilice un formato de archivo en columnas y mantenga los registros ordenados. En lugar de particionar por hora, mantenga los registros ordenados por marca de tiempo. Para las consultas en intervalos de tiempo más cortos, ordenar por marca de tiempo es casi tan eficaz como particionar por hora. Además, la clasificación por marca de tiempo no suele afectar el rendimiento de las consultas en intervalos de tiempo contados en días. Para obtener más información, consulte [Utilizar formatos de archivo en columnas](#performance-tuning-use-columnar-file-formats).

Tenga en cuenta que las consultas en tablas con decenas de miles de particiones funcionan mejor si hay predicados en todas las claves de partición. Esta es otra razón para diseñar un esquema de particiones para las consultas más comunes. Para obtener más información, consulte [Consulta de las particiones por igualdad](#performance-tuning-query-partitions-by-equality).

## Uso de la proyección de particiones
<a name="performance-tuning-use-partition-projection"></a>

La proyección de particiones es una característica de Athena que no almacena la información de la partición en el AWS Glue Data Catalog, sino como reglas en las propiedades de la tabla en AWS Glue. Cuando Athena planifica una consulta en una tabla configurada con proyección de particiones, lee las reglas de proyección de particiones de la tabla. Athena calcula las particiones para leerlas en la memoria en función de la consulta y las reglas en lugar de buscar las particiones en el AWS Glue Data Catalog.

Además de simplificar la administración de particiones, la proyección de particiones puede mejorar el rendimiento de los conjuntos de datos que tienen un gran número de particiones. Cuando una consulta incluye intervalos en lugar de valores específicos para las claves de partición, la búsqueda de particiones coincidentes en el catálogo lleva más tiempo a medida que aumenta el número de particiones. Con la proyección de particiones, el filtro se puede calcular en la memoria sin tener que consultar el catálogo, lo que puede ser mucho más rápido.

En determinadas circunstancias, la proyección de particiones puede reducir el rendimiento. Un ejemplo ocurre cuando una tabla se encuentra “dispersa”. Una tabla dispersa no contiene datos para todas las permutaciones de los valores de clave de partición descritos en la configuración de proyección de particiones. Con una tabla dispersa, el conjunto de particiones calculadas a partir de la consulta y la configuración de proyección de particiones se muestran en Amazon S3, incluso cuando no contienen datos.

Cuando utilice la proyección de particiones, asegúrese de incluir los predicados en todas las claves de partición. Limite el alcance de los valores posibles para evitar operaciones de lista innecesarias de Amazon S3. Imagine una clave de partición que tiene un intervalo de un millón de valores y una consulta que no tiene ningún filtro en esa clave de partición. Para ejecutar la consulta, Athena debe realizar al menos un millón de operaciones de lista en Amazon S3. Las consultas son más rápidas cuando se consultan valores específicos, independientemente de si se utiliza la proyección de particiones o se almacena la información de las particiones en el catálogo. Para obtener más información, consulte [Consulta de las particiones por igualdad](#performance-tuning-query-partitions-by-equality).

Al configurar una tabla para la proyección de particiones, asegúrese de que los intervalos que especifique sean razonables. Si una consulta no incluye un predicado en una clave de partición, se utilizan todos los valores del intervalo de esa clave. Si el conjunto de datos se creó en una fecha específica, utilice esa fecha como punto de partida para cualquier intervalo de fechas. Utilice `NOW` como el final de los intervalos de fechas. Evite los intervalos numéricos que tengan un gran número de valores y considere usar el tipo [inyectado](partition-projection-dynamic-id-partitioning.md#partition-projection-injection) en su lugar.

Para obtener más información sobre la proyección de particiones, consulte [Uso de proyección de particiones con Amazon Athena](partition-projection.md).

## Uso de índices de particiones
<a name="performance-tuning-use-partition-indexes"></a>

Los índices de particiones son una característica del AWS Glue Data Catalog que mejora el rendimiento de la búsqueda de particiones en las tablas que tienen un gran número de particiones.

La lista de particiones del catálogo es como una tabla de una base de datos relacional. La tabla tiene las columnas para las claves de partición y una columna adicional para la ubicación de la partición. Al consultar una tabla particionada, las ubicaciones de las particiones se buscan mediante el análisis de esta tabla.

Al igual que con las bases de datos relacionales, puede aumentar el rendimiento de las consultas gracias a la adición de índices. Puede agregar varios índices para admitir diferentes patrones de consulta. El índice de particiones del AWS Glue Data Catalog admite operadores de igualdad y comparación, como `>`, `>=` y `<` combinados con el operador `AND`. Para obtener más información, consulte [Trabajo con índices de partición en AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html) en la *Guía para desarrolladores de AWS Glue* y [Mejora del rendimiento de consultas de Amazon Athena con índices de particiones de AWS Glue Data Catalog](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/) en el *Blog de macrodatos de AWS*.

## Uso siempre de STRING como tipo para las claves de partición
<a name="performance-tuning-always-use-string-as-the-type-for-partition-keys"></a>

Cuando consulte las claves de partición, recuerde que Athena requiere que las claves de partición sean del tipo `STRING` para poder aplicar el filtrado de particiones en AWS Glue. Si el número de particiones no es pequeño, el uso de otros tipos puede reducir el rendimiento. Si los valores de las claves de partición son similares a una fecha o a un número, cámbielos al tipo adecuado en la consulta.

## Eliminación de las particiones antiguas y vacías
<a name="performance-tuning-remove-old-and-empty-partitions"></a>

Si elimina datos de una partición de Amazon S3 (por ejemplo, mediante el [ciclo de vida](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html) de Amazon S3), también debe eliminar la entrada de la partición del AWS Glue Data Catalog. Durante la planificación de la consulta, cualquier partición que coincida con la consulta aparece en Amazon S3. Si tiene muchas particiones vacías, la sobrecarga que supone listarlas puede ser perjudicial.

Además, si tiene muchos miles de particiones, considere la posibilidad de eliminar los metadatos de las particiones de los datos antiguos que ya no son relevantes. Por ejemplo, si las consultas nunca analizan datos de más de un año, puede eliminar periódicamente los metadatos de las particiones más antiguas. Si el número de particiones aumenta a decenas de miles, eliminar las particiones no utilizadas puede acelerar las consultas que no incluyen predicados en todas las claves de partición. Para obtener información sobre cómo incluir predicados en todas las claves de partición en las consultas, consulte [Consulta de las particiones por igualdad](#performance-tuning-query-partitions-by-equality).

## Consulta de las particiones por igualdad
<a name="performance-tuning-query-partitions-by-equality"></a>

Las consultas que incluyen predicados de igualdad en todas las claves de partición se ejecutan más rápido porque los metadatos de las particiones se pueden cargar de forma directa. Evite las consultas en las que una o más claves de partición no tengan un predicado o en las que el predicado seleccione un intervalo de valores. En este tipo de consultas, se debe filtrar la lista de todas las particiones para encontrar valores coincidentes. En la mayoría de las tablas, la sobrecarga es mínima, pero en las tablas con decenas de miles o más particiones, la sobrecarga puede llegar a ser significativa.

Si no es posible reescribir las consultas para filtrar las particiones por igualdad, puede probar la proyección de particiones. Para obtener más información, consulte [Uso de la proyección de particiones](#performance-tuning-use-partition-projection).

## Cómo evitar el uso de MSCK REPAIR TABLE para el mantenimiento de las particiones
<a name="performance-tuning-avoid-using-msck-repair-table-for-partition-maintenance"></a>

Como `MSCK REPAIR TABLE` puede tardar mucho en ejecutarse, solo agrega particiones nuevas y no elimina las antiguas, no es una forma eficaz de administrar las particiones (consulte [Consideraciones y limitaciones](msck-repair-table.md#msck-repair-table-considerations)).

Las particiones se administran mejor de forma manual mediante las [API del AWS Glue Data Catalog](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-catalog.html), [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) o los [rastreadores de AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/crawler-running.html). Como alternativa, puede utilizar la proyección de particiones, que elimina por completo la necesidad de administrar las particiones. Para obtener más información, consulte [Uso de proyección de particiones con Amazon Athena](partition-projection.md).

## Comprobar que las consultas sean compatibles con el esquema de particiones
<a name="performance-tuning-validate-that-your-queries-are-compatible-with-the-partitioning-scheme"></a>

Puede comprobar de antemano qué particiones se analizarán en una consulta mediante la instrucción [`EXPLAIN`](athena-explain-statement.md). Agregue el prefijo a la consulta con la palabra clave `EXPLAIN` y, a continuación, busque el fragmento de origen (por ejemplo, `Fragment 2 [SOURCE]`) de cada tabla cerca de la parte inferior del resultado `EXPLAIN`. Busque tareas en las que el lado derecho esté definido como una clave de partición. La línea inferior incluye una lista de todos los valores de esa clave de partición que se analizarán cuando se ejecute la consulta.

Por ejemplo, supongamos que tiene una consulta en una tabla con una clave de partición `dt` y agrega el prefijo a la consulta con `EXPLAIN`. Si los valores de la consulta son fechas y con un filtro se selecciona un intervalo de tres días, el resultado `EXPLAIN` puede ser similar a lo siguiente:

```
dt := dt:string:PARTITION_KEY
    :: [[2023-06-11], [2023-06-12], [2023-06-13]]
```

El resultado `EXPLAIN` muestra que el planificador encontró tres valores para esta clave de partición que coincidían con la consulta. También muestra cuáles son esos valores. Para obtener más información sobre el uso de `EXPLAIN`, consulte [Uso de EXPLAIN y EXPLAIN ANALYZE en Athena](athena-explain-statement.md) y [Descripción de los resultados de la instrucción EXPLAIN de Athena](athena-explain-statement-understanding.md).

## Utilizar formatos de archivo en columnas
<a name="performance-tuning-use-columnar-file-formats"></a>

Los formatos de archivo en columnas, como Parquet y ORC, están diseñados para cargas de trabajo de análisis distribuidas. Organizan los datos por columnas, no por filas. La organización de los datos en formato de columnas ofrece las siguientes ventajas:
+ Solo se cargan las columnas necesarias para la consulta.
+ Se reduce la cantidad total de datos que deben cargarse.
+ Los valores de las columnas se almacenan juntos, por lo que los datos se pueden comprimir de forma eficiente. 
+ Los archivos pueden contener metadatos que permiten que el motor omita la carga de datos innecesarios.

Como ejemplo de cómo se pueden utilizar los metadatos de los archivos, los metadatos de los archivos pueden contener información sobre los valores mínimos y máximos de una página de datos. Si los valores consultados no están dentro del intervalo indicado en los metadatos, se puede omitir la página.

Una forma de utilizar estos metadatos para mejorar el rendimiento es garantizar que los datos de los archivos estén ordenados. Por ejemplo, supongamos que tiene consultas que buscan registros en los que la entrada `created_at` se encuentra dentro de un periodo de tiempo breve. Si los datos están ordenados por la columna `created_at`, Athena puede usar los valores mínimo y máximo de los metadatos del archivo para omitir las partes innecesarias de los archivos de datos.

Cuando utilice formatos de archivo en columnas, asegúrese de que los archivos no sean demasiado pequeños. Como se indica en [Cómo evitar tener demasiados archivos](#performance-tuning-avoid-having-too-many-files), los conjuntos de datos con muchos archivos pequeños generan problemas de rendimiento. Esto se aplica aún más cuando se habla de formatos de archivo en columnas. En el caso de los archivos pequeños, la sobrecarga del formato de archivo en columnas supera las ventajas.

Tenga en cuenta que Parquet y ORC están organizados internamente por grupos de filas (Parquet) y bandas (ORC). El tamaño predeterminado para los grupos de filas es de 128 MB y para las bandas, de 64 MB. Si tiene muchas columnas, puede aumentar el tamaño del grupo de filas y de las bandas para obtener un mejor rendimiento. No se recomienda reducir el tamaño del grupo de filas o de las bandas a un valor inferior a sus valores predeterminados.

Para convertir otros formatos de datos a Parquet u ORC, puede utilizar ETL de AWS Glue o Athena. Para obtener más información, consulte [Conversión a formatos de columnas](columnar-storage.md#convert-to-columnar).

## Compresión de datos
<a name="performance-tuning-compress-data"></a>

Athena admite una amplia gama de formatos de compresión. La consulta de datos comprimidos es más rápida y económica, ya que se paga por el número de bytes analizados antes de la descompresión.

El formato [gzip](https://www.gnu.org/software/gzip/) ofrece buenas relaciones de compresión y es compatible con una amplia gama de herramientas y servicios. El formato [zstd](https://facebook.github.io/zstd/) (Zstandard) es un formato de compresión más reciente con un buen equilibrio entre rendimiento y relación de compresión.

Al comprimir archivos de texto, como datos JSON y CSV, intente lograr un equilibrio entre el número de archivos y su tamaño. La mayoría de los formatos de compresión requieren que el lector lea los archivos desde el principio. Esto significa que, en general, los archivos de texto comprimidos no se pueden procesar en paralelo. Los archivos grandes sin comprimir suelen dividirse entre los trabajos para lograr un mayor paralelismo durante el procesamiento de las consultas, pero esto no es posible con la mayoría de los formatos de compresión.

Como se explica en [Cómo evitar tener demasiados archivos](#performance-tuning-avoid-having-too-many-files), lo mejor es no tener demasiados archivos ni muy pocos. Como el número de archivos es el límite del número de trabajos que se pueden procesar en la consulta, esta regla se aplica aún más a los archivos comprimidos.

Para obtener más información sobre el uso de la compresión en Athena, consulte [Uso de la compresión en Athena](compression-formats.md).

## Creación de buckets para buscar claves con cardinalidad alta
<a name="performance-tuning-use-bucketing-for-lookups-on-keys-with-high-cardinality"></a>

La agrupación en buckets es una técnica para distribuir los registros en archivos separados según el valor de una de las columnas. Esto garantiza que todos los registros con el mismo valor estén en el mismo archivo. La agrupación en buckets resulta útil cuando se tiene una clave con una cardinalidad alta y muchas de las consultas buscan valores específicos de la clave.

Por ejemplo, supongamos que consulta un conjunto de registros para un usuario específico. Si los datos están agrupados por ID de usuario, Athena sabe de antemano qué archivos contienen registros para un ID específico y cuáles no. Esto permite a Athena leer solo los archivos que pueden contener el ID, lo que reduce de forma significativa la cantidad de datos leídos. También reduce el tiempo de computación que, de otro modo, se necesitaría para buscar el ID específico en los datos.

### Evitar la agrupación en buckets cuando las consultas buscan con frecuencia varios valores en una columna
<a name="performance-tuning-disadvantages-of-bucketing"></a>

La agrupación en buckets es menos valiosa cuando las consultas buscan con frecuencia múltiples valores en la columna por la que están agrupados los datos. Cuantos más valores se consulten, mayor será la probabilidad de que se tengan que leer todos los archivos o la mayoría de ellos. Por ejemplo, si tiene tres buckets y una consulta busca tres valores diferentes, es posible que deban leerse todos los archivos. La agrupación en buckets funciona mejor cuando las consultas buscan valores únicos.

Para obtener más información, consulte [Uso de particiones y asignación de buckets](ctas-partitioning-and-bucketing.md).

## Cómo evitar tener demasiados archivos
<a name="performance-tuning-avoid-having-too-many-files"></a>

Los conjuntos de datos que consisten en muchos archivos pequeños dan como resultado un rendimiento general de las consultas deficiente. Cuando Athena planifica una consulta, lista todas las ubicaciones de las particiones, lo que lleva tiempo. La administración y solicitud de cada archivo también supone una sobrecarga computacional. Por lo tanto, cargar un solo archivo más grande desde Amazon S3 es más rápido que cargar los mismos registros desde muchos archivos más pequeños.

En casos extremos, es posible que se encuentre con límites de servicio de Amazon S3. Amazon S3 admite hasta 5500 solicitudes por segundo en una sola partición de índice. Inicialmente, un bucket se trata como una partición de índice único, pero a medida que aumentan las cargas de solicitudes, se puede dividir en varias particiones de índice.

Amazon S3 analiza los patrones de solicitudes y los divide en función de los prefijos clave. Si su conjunto de datos consiste en muchos miles de archivos, las solicitudes procedentes de Athena pueden superar la cuota de solicitudes. Incluso con menos archivos, se puede superar la cuota si se realizan varias consultas simultáneas en el mismo conjunto de datos. Otras aplicaciones que tengan acceso a los mismos archivos pueden contribuir al número total de solicitudes.

Cuando se supera la tasa de solicitudes `limit`, Amazon S3 muestra el siguiente error. Este error se incluye en la información de estado de la consulta en Athena.

 SlowDown: reduzca la tasa de solicitudes. 

Para solucionar el problema, comience por determinar si el error se debe a una sola consulta o a varias consultas que leen los mismos archivos. Si se debe a lo último, coordine la ejecución de las consultas para que no se ejecuten al mismo tiempo. Para lograrlo, agregue un mecanismo de colas o incluso de reintentos en su aplicación.

Si al ejecutar una sola consulta se desencadena el error, intente combinar archivos de datos o modificar la consulta para leer menos archivos. El mejor momento para combinar archivos pequeños es antes de escribirlos. Para ello, tenga en cuenta las siguientes técnicas:
+ Cambie el proceso de escritura de los archivos para escribir archivos más grandes. Por ejemplo, puede almacenar los registros en búfer durante más tiempo antes de que se escriban. 
+ Coloque los archivos en una ubicación de Amazon S3 y utilice una herramienta como ETL de Glue para combinarlos en archivos más grandes. Luego, mueva los archivos más grandes a la ubicación a la que apunta la tabla. Para obtener más información, consulte [Lectura de archivos de entrada en grupos más grandes](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html) en la *Guía para desarrolladores de AWS Glue* y [¿Cómo puedo configurar un trabajo de ETL en AWS Glue para generar archivos más grandes?](https://repost.aws/knowledge-center/glue-job-output-large-files) en el *Centro de conocimientos de AWS re:Post*.
+ Reduzca el número de claves de partición. Si tiene demasiadas claves de partición, es posible que cada partición tenga solo algunos registros, lo que se traduce en un número excesivo de archivos pequeños. Para obtener información sobre cómo decidir qué particiones crear, consulte [Elección de claves de partición compatibles con las consultas](#performance-tuning-pick-partition-keys-that-will-support-your-queries).

## Cómo evitar jerarquías de almacenamiento adicionales más allá de la partición
<a name="performance-tuning-avoid-additional-storage-hierarchies-beyond-the-partition"></a>

Para evitar la sobrecarga de planificación de consultas, almacene los archivos en una estructura plana en cada ubicación de partición. No utilice jerarquías de directorios adicionales.

Cuando Athena planifica una consulta, lista todos los archivos de todas las particiones que coinciden con la consulta. Aunque Amazon S3 no tiene directorios propiamente dichos, la convención consiste en interpretar la barra diagonal `/` como un separador de directorios. Cuando Athena lista las ubicaciones de las particiones, lista de forma recursiva cualquier directorio que encuentre. Cuando los archivos de una partición se organizan en una jerarquía, se producen varias rondas de operaciones de lista.

Cuando todos los archivos están directamente en la ubicación de la partición, la mayoría de las veces solo se debe realizar una operación de lista. Sin embargo, se requieren varias operaciones de lista secuencial si tiene más de 1000 archivos en una partición, ya que Amazon S3 devuelve solo 1000 objetos por operación de lista. Tener más de 1000 archivos en una partición también puede provocar otros problemas de rendimiento más graves. Para obtener más información, consulte [Cómo evitar tener demasiados archivos](#performance-tuning-avoid-having-too-many-files). 

## Uso de SymlinkTextInputFormat solo cuando sea necesario
<a name="performance-tuning-use-symlinktextinputformat-only-when-necessary"></a>

El uso de la técnica [https://athena.guide/articles/stitching-tables-with-symlinktextinputformat](https://athena.guide/articles/stitching-tables-with-symlinktextinputformat) puede ser una forma de evitar situaciones en las que los archivos de una tabla no estén bien organizados en particiones. Por ejemplo, los enlaces simbólicos pueden resultar útiles cuando todos los archivos tienen el mismo prefijo o si los archivos con esquemas diferentes se encuentran en la misma ubicación.

Sin embargo, el uso de enlaces simbólicos agrega niveles de indirección a la ejecución de la consulta. Estos niveles de indirección afectan el rendimiento general. Se deben leer los archivos de enlace simbólico y se deben listar las ubicaciones que definen. Esto agrega varios viajes de ida y vuelta a Amazon S3 que las tablas de Hive habituales no requieren. En conclusión, `SymlinkTextInputFormat` solo debe utilizarse cuando no haya mejores opciones disponibles, como la reorganización de archivos.

# Uso de formatos de almacenamiento en columnas
<a name="columnar-storage"></a>

[Apache Parquet](https://parquet.apache.org) y [ORC](https://orc.apache.org/) son formatos de almacenamiento en columnas que están optimizados para una rápida recuperación de los datos y que se utilizan en las aplicaciones de análisis de AWS.

Los formatos de almacenamiento en columnas tienen las siguientes características que los hacen idóneos para su uso con Athena: 
+ *Compresión por columna, con el algoritmo de compresión seleccionado para cada tipo de datos de columna* para ahorrar espacio de almacenamiento en Amazon S3 y reducir el espacio de disco y las operaciones de E/S durante el procesamiento de consultas.
+ *La inserción de predicados* en Parquet y ORC permite que las consultas de Athena solo obtengan los bloques necesarios, lo que mejora el rendimiento de las consultas. Cuando una consulta de Athena obtiene valores de columna específicos de sus datos, utiliza las estadísticas de los predicados de bloque de datos, como los valores máximos o mínimos, para determinar si se debe leer u omitir el bloque. 
+ *La división de datos* en Parquet y ORC permite a Athena dividir la lectura de los datos entre varios lectores y aumentar el paralelismo durante el procesamiento de consultas. 

Para convertir sus datos sin procesar existentes de otros formatos de almacenamiento a Parquet u ORC, puede ejecutar [CREATE TABLE AS SELECT (CTAS)](ctas.md) en las consultas de Athena y especificar un formato de almacenamiento de datos como Parquet u ORC, o utilizar el rastreador de AWS Glue.

## Elección entre Parquet y ORC
<a name="columnar-storage-choosing"></a>

La elección entre ORC (Optimized Row Columnar) y Parquet depende de sus requisitos de uso específicos.

Apache Parquet proporciona esquemas eficientes de compresión y codificación de datos y es ideal para ejecutar consultas complejas y procesar grandes cantidades de datos. Parquet está optimizado para su uso con [Apache Arrow](https://arrow.apache.org/), lo que puede resultar ventajoso si utiliza herramientas relacionadas con Arrow.

ORC proporciona una forma eficiente de almacenar los datos de Hive. Los archivos ORC suelen ser más pequeños que los archivos Parquet, y los índices ORC pueden agilizar las consultas. Además, ORC admite tipos complejos, como estructuras, mapas y listas.

Cuando elija entre Parquet y ORC, tenga en cuenta los siguientes factores:

**Rendimiento de consultas**: dado que Parquet admite una gama más amplia de tipos de consultas, Parquet podría ser una mejor opción si planea realizar consultas complejas. 

**Tipos de datos complejos**: si utiliza tipos de datos complejos, ORC podría ser una mejor opción, ya que admite una gama más amplia de tipos de datos complejos.

**Tamaño de archivo**: si el espacio en disco es un problema, ORC suele producir archivos más pequeños, lo que puede reducir los costos de almacenamiento.

**Compresión**: tanto Parquet como ORC proporcionan una buena compresión, pero el mejor formato dependerá de su caso de uso específico.

**Evolución**: tanto Parquet como ORC admiten la evolución del esquema, lo que significa que puede agregar, eliminar o modificar columnas a lo largo del tiempo.

Tanto Parquet como ORC son buenas opciones para aplicaciones de macrodatos, pero tenga en cuenta los requisitos de su escenario antes de elegir. Es posible que desee realizar pruebas comparativas de sus datos y consultas para ver qué formato funciona mejor en su caso de uso.

## Conversión a formatos de columnas
<a name="convert-to-columnar"></a>

Las opciones para convertir fácilmente los datos de origen, como JSON o CSV, a un formato de columnas incluyen el uso de consultas [CREATE TABLE AS](ctas.md) o ejecución de trabajos en AWS Glue.
+ Puede usar consultas `CREATE TABLE AS` (CTAS) para convertir datos a Parquet u ORC en un solo paso. Para ver un ejemplo, consulte [Ejemplo: escritura de los resultados de la consulta en un formato diferente](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-format) en la página [Ejemplos de consultas CTAS](ctas-examples.md).
+ Para obtener información acerca del uso de Athena para ETL para transformar los datos de CSV a Parquet, consulte [Uso de CTAS e INSERT INTO en ETL y análisis de datos](ctas-insert-into-etl.md).
+ Para obtener información sobre cómo ejecutar un trabajo de AWS Glue para transformar datos en CSV a Parquet, consulte la sección “Transformar datos en formato CSV a Parquet” en la publicación del Blog de macrodatos de AWS [Crear una base de lago de datos con AWS Glue y Amazon S3](https://aws.amazon.com/blogs/big-data/build-a-data-lake-foundation-with-aws-glue-and-amazon-s3/). AWS Glue admite el uso de la misma técnica para convertir datos en CSV a ORC, o datos en JSON a Parquet u ORC.

# Uso de particiones y asignación de buckets
<a name="ctas-partitioning-and-bucketing"></a>

La creación de particiones y la asignación de buckets son dos formas de reducir la cantidad de datos que Athena debe analizar al ejecutar una consulta. La creación de particiones y la asignación de buckets son complementarias y se pueden utilizar juntas. Reducir la cantidad de datos analizados mejora el rendimiento y reduce los costos. Para obtener pautas generales sobre el rendimiento de las consultas de Athena, consulte [Los 10 mejores consejos para ajustar el rendimiento de Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/).

**Topics**
+ [¿Qué es la creación de particiones?](ctas-partitioning-and-bucketing-what-is-partitioning.md)
+ [¿Qué es la asignación de buckets?](ctas-partitioning-and-bucketing-what-is-bucketing.md)
+ [Recursos adicionales](ctas-partitioning-and-bucketing-additional-resources.md)

# ¿Qué es la creación de particiones?
<a name="ctas-partitioning-and-bucketing-what-is-partitioning"></a>

Crear particiones significa organizar los datos en directorios (o “prefijos”) en Amazon S3 en función de una propiedad concreta de los datos. Estas propiedades se denominan claves de partición. Una clave de partición común es la fecha o alguna otra unidad de tiempo, como el año o el mes. Sin embargo, un conjunto de datos se puede particionar en más de una clave. Por ejemplo, los datos sobre las ventas de productos pueden particionarse por fecha, categoría de producto y mercado.

## Decidir cómo crear particiones
<a name="ctas-partitioning-and-bucketing-deciding-how-to-partition"></a>

Las propiedades que se utilizan siempre o con frecuencia en las consultas y que tienen una cardinalidad baja son buenas candidatas para las claves de partición. Hay una disyuntiva entre tener demasiadas particiones y tener muy pocas. Con demasiadas particiones, el aumento del número de archivos genera una sobrecarga. El filtrado de las propias particiones también supone una sobrecarga. Con muy pocas particiones, las consultas suelen tener que analizar más datos.

## Creación de una tabla particionada
<a name="ctas-partitioning-and-bucketing-creating-a-partitioned-table"></a>

Cuando un conjunto de datos está particionado, puede crear una tabla particionada en Athena. Una tabla particionada es una tabla que tiene claves de partición. Cuando se utiliza `CREATE TABLE`, se agregan particiones a la tabla. Cuando se utiliza `CREATE TABLE AS`, las particiones que se crean en Amazon S3 se agregan automáticamente a la tabla.

En una instrucción `CREATE TABLE`, se especifican las claves de partición en la cláusula `PARTITIONED BY (column_name data_type)`. En una instrucción `CREATE TABLE AS`, se especifican las claves de partición en una cláusula `WITH (partitioned_by = ARRAY['partition_key'])` o `WITH (partitioning = ARRAY['partition_key'])` en las tablas de Iceberg. Por motivos de rendimiento, las claves de partición siempre deben ser del tipo `STRING`. Para obtener más información, consulte [Uso de una cadena como tipo de datos para las claves de partición](data-types-timestamps.md#data-types-timestamps-partition-key-types).

Para obtener información adicional sobre la sintaxis de `CREATE TABLE` y `CREATE TABLE AS`, consulte [CREATE TABLE](create-table.md) y [Propiedades de la tabla CTAS](create-table-as.md#ctas-table-properties).

## Consulta de tablas particionadas
<a name="ctas-partitioning-and-bucketing-querying-partitioned-tables"></a>

Cuando se consulta una tabla particionada, Athena usa los predicados de la consulta para filtrar la lista de particiones. A continuación, utiliza las ubicaciones de las particiones coincidentes para procesar los archivos encontrados. Athena puede reducir de manera eficiente la cantidad de datos analizados simplemente al no leer los datos de las particiones que no coinciden con los predicados de la consulta.

### Ejemplos
<a name="ctas-partitioning-and-bucketing-partitioned-table-example-queries"></a>

Supongamos que tiene una tabla particionada en `sales_date` y `product_category` y quiere saber los ingresos totales de una semana en una categoría específica. Debe incluir predicados en las columnas `sales_date` y `product_category` para garantizar que Athena analice solo la cantidad mínima de datos, como en el siguiente ejemplo.

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' 
AND product_category = 'Toys'
```

Supongamos que tiene un conjunto de datos que está particionado por fecha, pero que también tiene una marca de tiempo detallada.

Con las tablas de Iceberg, puede declarar que una clave de partición tiene una relación con una columna, pero con las tablas de Hive, el motor de consultas no conoce las relaciones entre las columnas y las claves de partición. Por este motivo, debe incluir un predicado tanto en la columna como en la clave de partición de la consulta para asegurarse de que la consulta no analice más datos de los necesarios.

Por ejemplo, supongamos que la tabla `sales` del ejemplo anterior también tiene una columna `sold_at` del tipo de datos `TIMESTAMP`. Si desea obtener los ingresos solo para un intervalo de tiempo específico, debe escribir la consulta de la siguiente manera:

```
SELECT SUM(amount) AS total_revenue 
FROM sales 
WHERE sales_date = '2023-02-28' 
AND sold_at BETWEEN TIMESTAMP '2023-02-28 10:00:00' AND TIMESTAMP '2023-02-28 12:00:00' 
AND product_category = 'Toys'
```

Para obtener más información sobre esta diferencia entre las consultas de las tablas de Hive e Iceberg, consulte [Cómo escribir consultas para campos de marca de tiempo que también se encuentren particionados por tiempo](data-types-timestamps.md#data-types-timestamps-how-to-write-queries-for-timestamp-fields-that-are-also-time-partitioned).

# ¿Qué es la asignación de buckets?
<a name="ctas-partitioning-and-bucketing-what-is-bucketing"></a>

La asignación de buckets es una forma de organizar los registros de un conjunto de datos en categorías denominadas buckets.

Este significado de bucket y creación de buckets es diferente del de bucket de Amazon S3 y no debe confundirse con este. En la asignación de buckets para datos, los registros que tienen el mismo valor para una propiedad se incluyen en el mismo bucket. Los registros se distribuyen de la forma más uniforme posible entre los buckets, de modo que cada uno de ellos tenga aproximadamente la misma cantidad de datos.

En la práctica, los buckets son archivos y una función hash determina el bucket al que se asigna un registro. Un conjunto de datos agrupado en buckets tendrá uno o más archivos por bucket y partición. El bucket al que pertenece un archivo está codificado en el nombre del archivo.

## Beneficios de la asignación de buckets
<a name="ctas-partitioning-and-bucketing-bucketing-benefits"></a>

La asignación de buckets es útil cuando un conjunto de datos está agrupado en buckets según una propiedad específica y se desean recuperar registros en los que esa propiedad tiene un valor determinado. Como los datos están agrupados en buckets, Athena puede utilizar el valor para determinar los archivos que se van a examinar. Por ejemplo, supongamos que un conjunto de datos está agrupado en buckets por `customer_id` y que usted desea buscar todos los registros de un cliente específico. Athena determina el bucket que contiene esos registros y solo lee los archivos de ese bucket.

Las columnas que presentan una alta cardinalidad (es decir, tienen muchos valores distintos), están distribuidas de manera uniforme y se consultan en busca de valores específicos con frecuencia, se consideran buenas candidatas para la asignación de datos.

**nota**  
Athena no admite el uso de `INSERT INTO` para agregar nuevos registros a tablas agrupadas en buckets.

## Tipos de datos admitidos para filtrado en columnas en buckets
<a name="ctas-partitioning-and-bucketing-data-types-supported-for-filtering-on-bucketed-columns"></a>

Puede agregar filtros en columnas agrupadas en buckets con determinados tipos de datos. Athena admite el filtrado en columnas agrupadas en buckets con los siguientes tipos de datos:
+ BOOLEANO
+ BYTE
+ DATE
+ DOUBLE
+ FLOAT
+ INT
+ LONG
+ SHORT
+ STRING
+ VARCHAR

## Soporte para Hive y Spark
<a name="ctas-partitioning-and-bucketing-hive-and-spark-support"></a>

La versión 2 del motor de Athena admite conjuntos de datos agrupados en buckets mediante el algoritmo de bucket Hive, y la versión 3 del motor de Athena también admite el algoritmo de bucket Apache Spark. Hive es el bucket predeterminado. Si el conjunto de datos está agrupado en buckets mediante el algoritmo Spark, use la cláusula `TBLPROPERTIES` para establecer el valor de la propiedad `bucketing_format` en `spark`.

**nota**  
Athena tiene un límite de 100 particiones por consulta `CREATE TABLE AS SELECT` ([CTAS](ctas.md)). Del mismo modo, solo puede agregar un máximo de 100 particiones a una tabla de destino con una instrucción [INSERT INTO](insert-into.md).  
Si supera esta limitación, es posible que reciba el mensaje de error HIVE\$1TOO\$1MANY\$1OPEN\$1PARTITIONS: Exceeded limit of 100 open writers for partitions/buckets (HIVE\$1TOO\$1MANY\$1OPEN\$1PARTITIONS: Se ha superado el límite de 100 autores abiertos para particiones/buckets). Para evitar esta limitación, puede utilizar una instrucción CTAS y una serie de instrucciones `INSERT INTO` que crean o insertan hasta 100 particiones cada una. Para obtener más información, consulte [Uso de CTAS e INSERT INTO para evitar el límite de 100 particiones](ctas-insert-into.md).

## Ejemplo de asignación de buckets con CREATE TABLE
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-example"></a>

Si desea crear una tabla para un conjunto de datos agrupado en buckets existente, use la cláusula `CLUSTERED BY (column)` seguida de la cláusula `INTO N BUCKETS`. La cláusula `INTO N BUCKETS` especifica el número de buckets en los que se agrupan los datos.

En el siguiente ejemplo `CREATE TABLE`, el conjunto de datos `sales` se agrupa por `customer_id` en 8 buckets mediante el algoritmo Spark. La instrucción `CREATE TABLE` usa las cláusulas `CLUSTERED BY` y `TBLPROPERTIES` para establecer las propiedades en consecuencia.

```
CREATE EXTERNAL TABLE sales (...) 
... 
CLUSTERED BY (`customer_id`) INTO 8 BUCKETS 
... 
TBLPROPERTIES ( 
  'bucketing_format' = 'spark' 
)
```

## Ejemplo de asignación de buckets con CREATE TABLE AS (CTAS)
<a name="ctas-partitioning-and-bucketing-bucketing-create-table-as-example"></a>

Para especificar la asignación de buckets con `CREATE TABLE AS`, utilice los parámetros `bucketed_by` y `bucket_count`, como en el siguiente ejemplo.

```
CREATE TABLE sales 
WITH ( 
  ... 
  bucketed_by = ARRAY['customer_id'], 
  bucket_count = 8 
) 
AS SELECT ...
```

## Ejemplo de consulta de asignación de buckets
<a name="ctas-partitioning-and-bucketing-bucketing-query-example"></a>

En el siguiente ejemplo de consulta, se buscan los nombres de los productos que un cliente específico ha comprado en el transcurso de una semana.

```
SELECT DISTINCT product_name 
FROM sales 
WHERE sales_date BETWEEN '2023-02-27' AND '2023-03-05' 
AND customer_id = 'c123'
```

Si esta tabla está particionada por `sales_date` y agrupada en buckets por `customer_id`, Athena puede calcular el bucket en el que se encuentran los registros del cliente. Como máximo, Athena lee un archivo por partición.

# Recursos adicionales
<a name="ctas-partitioning-and-bucketing-additional-resources"></a>
+ Para ver un ejemplo de `CREATE TABLE AS` en el que se crean tablas agrupadas en buckets y particionadas, consulte [Ejemplo: creación de tablas agrupadas en buckets y particionadas](https://docs.aws.amazon.com/athena/latest/ug/ctas-examples.html#ctas-example-bucketed).
+ Para obtener información sobre cómo implementar el uso de buckets en lagos de datos de AWS, incluido el uso de una instrucción CTAS de Athena, AWS Glue para Apache Spark y el uso de buckets para tablas de Apache Iceberg, consulte la publicación en el blog de Big Data de AWS [Optimizar la disposición de datos mediante el uso de buckets con Amazon Athena y AWS Glue para acelerar las consultas posteriores](https://aws.amazon.com/blogs/big-data/optimize-data-layout-by-bucketing-with-amazon-athena-and-aws-glue-to-accelerate-downstream-queries/). 

# Partición de datos
<a name="partitions"></a>

La partición de los datos le permite restringir el volumen de datos que explora cada consulta, lo que mejora el rendimiento y reduce los costos. Puede particionar los datos por cualquier clave. Una práctica común consiste en particionar los datos en función del tiempo, lo que a menudo conduce a un esquema de partición de varios niveles. Por ejemplo, si un cliente recibe datos cada hora, podría elegir una partición por año, mes, día y hora. Otro cliente, que recibe datos procedentes de muchos orígenes distintos, pero que solo se cargan una vez al día, puede basar la partición en un identificador del origen de datos y en la fecha.

Athena puede utilizar particiones de estilo de Apache Hive, cuyas rutas de datos contienen pares de valores de clave conectados por signos de igual (por ejemplo, `country=us/...` o `year=2021/month=01/day=26/...`). Por lo tanto, las rutas incluyen los nombres de las claves de partición y los valores que representa cada ruta. Para cargar nuevas particiones de Hive en una tabla particionada, puede utilizar el comando [MSCK REPAIR TABLE](msck-repair-table.md), que solo funciona con particiones de estilo de Hive.

Athena también puede utilizar esquemas de partición de estilos que no son de Hive. Por ejemplo, los registros de CloudTrail y los flujos de entrega de Firehose utilizan componentes de ruta independientes para partes de fecha, como `data/2021/01/26/us/6fc7845e.json`. Para aquellas particiones que no son del estilo de Hive, se utiliza [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) para agregar las particiones manualmente.

## Consideraciones y limitaciones
<a name="partitions-considerations-limitations"></a>

Al usar la partición, tenga en cuenta los siguientes puntos:
+ Si consulta una tabla con particiones y especifica la partición en la cláusula `WHERE`, Athena analiza los datos solo de esa partición.
+ Si efectúa consultas de los buckets de Amazon S3 con un gran número de objetos y los datos no están particionados, dichas consultas pueden afectar los límites de tasa de solicitudes `GET` en Amazon S3 y dar lugar a excepciones de Amazon S3. Para evitar errores, divida los datos. Plantéese también ajustar las tasas de solicitud de Amazon S3. Para obtener más información, consulte [Patrones de diseño de prácticas recomendadas: optimización del rendimiento de Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/request-rate-perf-considerations.html).
+ Las ubicaciones de partición que se van a utilizar con Athena deben utilizar el protocolo `s3` (por ejemplo, `s3://amzn-s3-demo-bucket/folder/`). En Athena, las ubicaciones que utilizan otros protocolos (por ejemplo, `s3a://amzn-s3-demo-bucket/folder/`) producirán errores de consulta cuando se ejecuten consultas `MSCK REPAIR TABLE` en las tablas que contienen. 
+ Asegúrese de que la ruta de Amazon S3 esté en minúsculas, en lugar de usar también mayúsculas en la inicial (por ejemplo, `userid` en lugar de `userId`). Si la ruta de S3 usa mayúsculas en la inicial, `MSCK REPAIR TABLE` no agrega las particiones a AWS Glue Data Catalog. Para obtener más información, consulte [MSCK REPAIR TABLE](msck-repair-table.md).
+ Dado que `MSCK REPAIR TABLE` analiza una carpeta y sus subcarpetas para encontrar un esquema de partición coincidente, asegúrese de mantener los datos de tablas separadas en jerarquías de carpetas separadas. Por ejemplo, supongamos que tiene los datos de la tabla 1 en `s3://amzn-s3-demo-bucket1` y los datos de la tabla 2 en `s3://amzn-s3-demo-bucket1/table-2-data`. Si ambas tablas están particionadas por cadena, `MSCK REPAIR TABLE` agregará las particiones de la tabla 2 a la tabla 1. Para evitarlo, utilice estructuras de carpetas independientes, como `s3://amzn-s3-demo-bucket1` y `s3://amzn-s3-demo-bucket2` en su lugar. Tenga en cuenta que este comportamiento es coherente con Amazon EMR y Apache Hive.
+ Si actualmente utiliza AWS Glue Data Catalog con Athena, consulte los [puntos de conexión y cuotas de AWS Glue](https://docs.aws.amazon.com/general/latest/gr/glue.html) para ver las cuotas de servicio de las particiones por cuenta y por tabla. 
  + Aunque Athena admite consultas de tablas de AWS Glue que tienen 10 millones de particiones, no puede leer más de 1 millón de particiones en un solo escaneo. En estos escenarios, la indexación de particiones puede ser beneficiosa. Para obtener más información, consulte el artículo del Blog de macrodatos de AWS [Improve Amazon Athena query performance using AWS Glue Data Catalog partition indexes](https://aws.amazon.com/blogs/big-data/improve-amazon-athena-query-performance-using-aws-glue-data-catalog-partition-indexes/).
+ Para solicitar un aumento de la cuota de particiones si está utilizando el AWS Glue Data Catalog, vaya a la [consola de Service Quotas de AWS Glue](https://console.aws.amazon.com/servicequotas/home?region=us-east-1#!/services/glue/quotas).

## Creación y carga de una tabla con datos con particiones
<a name="partitions-creating-loading"></a>

Para crear una tabla que utiliza particiones, utilice la cláusula `PARTITIONED BY` de la instrucción [CREATE TABLE](create-table.md). La cláusula `PARTITIONED BY` define las claves en las que se llevará a cabo la partición de los datos, como en el siguiente ejemplo. La cláusula `LOCATION` especifica la ubicación raíz de los datos particionados.

```
CREATE EXTERNAL TABLE users (
first string,
last string,
username string
)
PARTITIONED BY (id string)
STORED AS parquet
LOCATION 's3://amzn-s3-demo-bucket'
```

Después de crear la tabla, cargará los datos en las particiones para poder consultarlos. Para las particiones de estilo Hive, se ejecuta [MSCK REPAIR TABLE](msck-repair-table.md). Para las particiones que no son del estilo de Hive, se utiliza [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) para agregar las particiones manualmente.

## Preparación de datos de estilo de Hive y no compatibles con Hive para consultas
<a name="partitions-preparing-data"></a>

En las siguientes secciones, se muestra cómo preparar datos de estilo de Hive y no compatibles con Hive para consultas en Athena.

### Escenario 1: datos almacenados en Amazon S3 en formato Hive
<a name="scenario-1-data-already-partitioned-and-stored-on-s3-in-hive-format"></a>

En este escenario, las particiones están almacenadas en Amazon S3 en carpetas distintas. Por ejemplo, esta es una lista parcial de muestras de impresiones de anuncios que genera el comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/ls.html), que enumera los objetos de S3 con un prefijo especificado:

```
aws s3 ls s3://elasticmapreduce/samples/hive-ads/tables/impressions/

    PRE dt=2009-04-12-13-00/
    PRE dt=2009-04-12-13-05/
    PRE dt=2009-04-12-13-10/
    PRE dt=2009-04-12-13-15/
    PRE dt=2009-04-12-13-20/
    PRE dt=2009-04-12-14-00/
    PRE dt=2009-04-12-14-05/
    PRE dt=2009-04-12-14-10/
    PRE dt=2009-04-12-14-15/
    PRE dt=2009-04-12-14-20/
    PRE dt=2009-04-12-15-00/
    PRE dt=2009-04-12-15-05/
```

Aquí los registros se almacenan con el nombre de columna (dt) definido según incrementos de fecha, hora y minuto. Cuando se especifica DDL con la ubicación de la carpeta principal, el esquema y el nombre de la columna particionada, Athena puede consultar los datos de las subcarpetas.

#### Creación de la tabla
<a name="creating-a-table"></a>

Para obtener una tabla de estos datos, cree una partición basada en “dt”, como en la siguiente instrucción DDL de Athena:

```
CREATE EXTERNAL TABLE impressions (
    requestBeginTime string,
    adId string,
    impressionId string,
    referrer string,
    userAgent string,
    userCookie string,
    ip string,
    number string,
    processId string,
    browserCookie string,
    requestEndTime string,
    timers struct<modelLookup:string, requestTime:string>,
    threadId string,
    hostname string,
    sessionId string)
PARTITIONED BY (dt string)
ROW FORMAT  serde 'org.apache.hive.hcatalog.data.JsonSerDe'
LOCATION 's3://elasticmapreduce/samples/hive-ads/tables/impressions/' ;
```

Esta tabla utiliza el serializador-deserializador JSON nativo de Hive para leer los datos JSON almacenados en Amazon S3. Para obtener más información acerca de los formatos admitidos, consulte [Elección de un valor de SerDe para los datos](supported-serdes.md).

#### Ejecución de MSCK REPAIR TABLE
<a name="run-msck-repair-table"></a>

Después de ejecutar la consulta `CREATE TABLE`, ejecute el comando `MSCK REPAIR TABLE` del editor de consultas de Athena para cargar las particiones, como en el siguiente ejemplo.

```
MSCK REPAIR TABLE impressions
```

Cuando ejecuta este comando, los datos están listos para consultarlos.

#### Consulta de los datos
<a name="query-the-data"></a>

Consulte los datos de la tabla de impresiones utilizando la columna de partición. A continuación se muestra un ejemplo:

```
SELECT dt,impressionid FROM impressions WHERE dt<'2009-04-12-14-00' and dt>='2009-04-12-13-00' ORDER BY dt DESC LIMIT 100
```

La consulta deberá mostrar resultados similares a los siguientes:

```
2009-04-12-13-20    ap3HcVKAWfXtgIPu6WpuUfAfL0DQEc
2009-04-12-13-20    17uchtodoS9kdeQP1x0XThKl5IuRsV
2009-04-12-13-20    JOUf1SCtRwviGw8sVcghqE5h0nkgtp
2009-04-12-13-20    NQ2XP0J0dvVbCXJ0pb4XvqJ5A4QxxH
2009-04-12-13-20    fFAItiBMsgqro9kRdIwbeX60SROaxr
2009-04-12-13-20    V4og4R9W6G3QjHHwF7gI1cSqig5D1G
2009-04-12-13-20    hPEPtBwk45msmwWTxPVVo1kVu4v11b
2009-04-12-13-20    v0SkfxegheD90gp31UCr6FplnKpx6i
2009-04-12-13-20    1iD9odVgOIi4QWkwHMcOhmwTkWDKfj
2009-04-12-13-20    b31tJiIA25CK8eDHQrHnbcknfSndUk
```

### Escenario 2: Los datos no están particionados en formato Hive
<a name="scenario-2-data-is-not-partitioned"></a>

En el siguiente ejemplo, el comando `aws s3 ls` muestra registros de [ELB](elasticloadbalancer-classic-logs.md) almacenados en Amazon S3. Tenga en cuenta que el diseño de datos no utiliza pares `key=value` y, por lo tanto, no está en formato Hive. (La opción `--recursive` para el comando `aws s3 ls` especifica que se enumeran todos los objetos o archivos del directorio especificado o con el prefijo indicado).

```
aws s3 ls s3://athena-examples-myregion/elb/plaintext/ --recursive

2016-11-23 17:54:46   11789573 elb/plaintext/2015/01/01/part-r-00000-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    8776899 elb/plaintext/2015/01/01/part-r-00001-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9309800 elb/plaintext/2015/01/01/part-r-00002-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9412570 elb/plaintext/2015/01/01/part-r-00003-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47   10725938 elb/plaintext/2015/01/01/part-r-00004-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:46    9439710 elb/plaintext/2015/01/01/part-r-00005-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47          0 elb/plaintext/2015/01/01_$folder$
2016-11-23 17:54:47    9012723 elb/plaintext/2015/01/02/part-r-00006-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    7571816 elb/plaintext/2015/01/02/part-r-00007-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:47    9673393 elb/plaintext/2015/01/02/part-r-00008-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11979218 elb/plaintext/2015/01/02/part-r-00009-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    9546833 elb/plaintext/2015/01/02/part-r-00010-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   10960865 elb/plaintext/2015/01/02/part-r-00011-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48          0 elb/plaintext/2015/01/02_$folder$
2016-11-23 17:54:48   11360522 elb/plaintext/2015/01/03/part-r-00012-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48   11211291 elb/plaintext/2015/01/03/part-r-00013-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:48    8633768 elb/plaintext/2015/01/03/part-r-00014-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11891626 elb/plaintext/2015/01/03/part-r-00015-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49    9173813 elb/plaintext/2015/01/03/part-r-00016-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49   11899582 elb/plaintext/2015/01/03/part-r-00017-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:49          0 elb/plaintext/2015/01/03_$folder$
2016-11-23 17:54:50    8612843 elb/plaintext/2015/01/04/part-r-00018-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50   10731284 elb/plaintext/2015/01/04/part-r-00019-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9984735 elb/plaintext/2015/01/04/part-r-00020-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    9290089 elb/plaintext/2015/01/04/part-r-00021-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:50    7896339 elb/plaintext/2015/01/04/part-r-00022-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8321364 elb/plaintext/2015/01/04/part-r-00023-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/04_$folder$
2016-11-23 17:54:51    7641062 elb/plaintext/2015/01/05/part-r-00024-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   10253377 elb/plaintext/2015/01/05/part-r-00025-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8502765 elb/plaintext/2015/01/05/part-r-00026-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51   11518464 elb/plaintext/2015/01/05/part-r-00027-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7945189 elb/plaintext/2015/01/05/part-r-00028-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    7864475 elb/plaintext/2015/01/05/part-r-00029-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51          0 elb/plaintext/2015/01/05_$folder$
2016-11-23 17:54:51   11342140 elb/plaintext/2015/01/06/part-r-00030-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:51    8063755 elb/plaintext/2015/01/06/part-r-00031-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9387508 elb/plaintext/2015/01/06/part-r-00032-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9732343 elb/plaintext/2015/01/06/part-r-00033-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11510326 elb/plaintext/2015/01/06/part-r-00034-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    9148117 elb/plaintext/2015/01/06/part-r-00035-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52          0 elb/plaintext/2015/01/06_$folder$
2016-11-23 17:54:52    8402024 elb/plaintext/2015/01/07/part-r-00036-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52    8282860 elb/plaintext/2015/01/07/part-r-00037-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:52   11575283 elb/plaintext/2015/01/07/part-r-00038-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53    8149059 elb/plaintext/2015/01/07/part-r-00039-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10037269 elb/plaintext/2015/01/07/part-r-00040-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53   10019678 elb/plaintext/2015/01/07/part-r-00041-ce65fca5-d6c6-40e6-b1f9-190cc4f93814.txt
2016-11-23 17:54:53          0 elb/plaintext/2015/01/07_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015/01_$folder$
2016-11-23 17:54:53          0 elb/plaintext/2015_$folder$
```

#### Ejecución de ALTER TABLE ADD PARTITION
<a name="run-alter-table-add-partition"></a>

Dado que los datos no están en formato Hive, no se puede utilizar el comando `MSCK REPAIR TABLE` para agregar las particiones a la tabla después de crearla. Como alternativa, puede usar el comando [ALTER TABLE ADD PARTITION](alter-table-add-partition.md) para agregar cada partición manualmente. Por ejemplo, para cargar los datos en s3://athena-examples-*myregion*/elb/plaintext/2015/01/01/, puede ejecutar la siguiente consulta. Tenga en cuenta que no se requiere una columna de partición independiente para cada carpeta de Amazon S3 y que el valor de la clave de partición puede ser diferente de la clave de Amazon S3.

```
ALTER TABLE elb_logs_raw_native_part ADD PARTITION (dt='2015-01-01') location 's3://athena-examples-us-west-1/elb/plaintext/2015/01/01/'
```

Si ya existe una partición, recibirá el error La partición ya existe. Para evitar este error, puede usar la cláusula `IF NOT EXISTS`. Para obtener más información, consulte [ALTER TABLE ADD PARTITION](alter-table-add-partition.md). Para eliminar una partición, puede utilizar [ALTER TABLE DROP PARTITION](alter-table-drop-partition.md). 

## Consideración de la proyección de particiones
<a name="partitions-partition-projection"></a>

Para evitar tener que administrar particiones por cuenta propia, puede usar la proyección de particiones. La proyección de particiones es una opción para tablas divididas en muchas partes cuya estructura se conoce de antemano. En la proyección de particiones, los valores de partición y las ubicaciones se calculan a partir de las propiedades de tabla que configure, en lugar de leerlos desde un repositorio de metadatos. Dado que los cálculos hechos en la memoria son más rápidos que la búsqueda remota, el uso de la proyección de particiones puede reducir significativamente los tiempos de ejecución de las consultas. 

Para obtener más información, consulte [Uso de proyección de particiones con Amazon Athena](partition-projection.md).

## Recursos adicionales
<a name="partitions-additional-resources"></a>
+ Para obtener información sobre las opciones de partición de datos de Firehose, consulte [Ejemplo de Amazon Data Firehose](partition-projection-kinesis-firehose-example.md).
+ También puede automatizar la adición de particiones con el [controlador JDBC](connect-with-jdbc.md). 
+ Puede utilizar CTAS e INSERT INTO para particionar un conjunto de datos. Para obtener más información, consulte [Uso de CTAS e INSERT INTO en ETL y análisis de datos](ctas-insert-into-etl.md).

# Uso de proyección de particiones con Amazon Athena
<a name="partition-projection"></a>

Puede utilizar la proyección de particiones en Athena para acelerar el procesamiento de consultas de tablas altamente particionadas y automatizar la administración de particiones.

En la proyección de particiones, Athena calcula los valores de partición y las ubicaciones utilizando las propiedades de tabla que configure directamente en la tabla de AWS Glue. Las propiedades de la tabla permiten a Athena “proyectar” o determinar la información de partición necesaria en lugar de tener que realizar una búsqueda de metadatos en el AWS Glue Data Catalog que consume más tiempo. Dado que las operaciones en memoria suelen ser más rápidas que las operaciones remotas, la proyección de particiones puede reducir el tiempo de ejecución de las consultas en tablas altamente particionadas. Dependiendo de las características específicas de la consulta y los datos subyacentes, la proyección de particiones puede reducir significativamente el tiempo de ejecución de la consulta para las consultas que están restringidas en la recuperación de metadatos de partición.

## Información de la eliminación de particiones frente a la proyección de particiones
<a name="partition-projection-pruning-vs-projection"></a>

La poda de partición recopila metadatos y los “poda” solo en las particiones que se aplican a su consulta. Por lo general, esto acelera las consultas. Athena utiliza la poda de particiones para todas las tablas con columnas de partición, incluidas las tablas configuradas para la proyección de particiones.

Normalmente, al procesar consultas, Athena realiza una llamada `GetPartitions` al AWS Glue Data Catalog antes de realizar la poda de partición. Si una tabla tiene un gran número de particiones, el uso de `GetPartitions` puede afectar negativamente el rendimiento. Para evitar esto, puede usar la proyección de particiones. La proyección de particiones permite a Athena evitar llamadas a `GetPartitions` porque la configuración de proyección de particiones proporciona a Athena toda la información necesaria para construir las particiones en sí.

## Procedimientos para usar la proyección de particiones
<a name="partition-projection-using"></a>

Para utilizar la proyección de particiones, especifique los intervalos de valores de partición y tipos de proyección para cada columna de partición en las propiedades de tabla en el AWS Glue Data Catalog o en el [metaalmacén externo de Hive](connect-to-data-source-hive.md). Estas propiedades personalizadas en la tabla le permiten a Athena saber qué patrones de partición esperar cuando ejecuta una consulta en la tabla. Durante la ejecución de la consulta, Athena utiliza esta información para proyectar los valores de partición en lugar de recuperarlos desde el metaalmacén externo de Hive o AWS Glue Data Catalog. Esto no solo reduce el tiempo de ejecución de la consulta, sino que también automatiza la administración de particiones, ya que elimina la necesidad de crear manualmente particiones en Athena, el metaalmacén externo de Hive o AWS Glue.

**importante**  
Habilitar la proyección de particiones en una tabla hace que Athena ignore los metadatos de partición registrados en la tabla en el metaalmacén externo de Hive o AWS Glue Data Catalog.

## Algunos casos de uso
<a name="partition-projection-use-cases"></a>

Entre los escenarios en los que la proyección de particiones es útil se incluyen los siguientes:
+ Las consultas contra una tabla altamente particionada no se completan tan rápido como le gustaría.
+ Las particiones se agregan regularmente a las tablas a medida que se crean nuevas particiones de fecha u hora en los datos. Con la proyección de particiones, puede configurar intervalos de fechas relativos que se pueden utilizar a medida que llegan nuevos datos. 
+ Tiene datos altamente particionados en Amazon S3. Los datos no son prácticos para modelar en su metaalmacén AWS Glue Data Catalog o Hive, y sus consultas solo leen pequeñas partes de ellos.

### Estructuras de partición proyectables
<a name="partition-projection-known-data-structures"></a>

La proyección de particiones se configura más fácilmente cuando las particiones siguen un patrón predecible como, entre otros, los siguientes:
+ **Enteros**: cualquier secuencia continua de enteros como `[1, 2, 3, 4, ..., 1000]` o `[0500, 0550, 0600, ..., 2500]`.
+ **Fechas**: cualquier secuencia continua de fechas o fechas y horas como `[20200101, 20200102, ..., 20201231]` o `[1-1-2020 00:00:00, 1-1-2020 01:00:00, ..., 12-31-2020 23:00:00]`.
+ **Valores enumerados**: un conjunto finito de valores enumerados como códigos de aeropuertos o Regiones de AWS.
+ **Registros de Servicio de AWS**: normalmente, los registros de Servicio de AWS tienen una estructura conocida cuyo esquema de particiones puede especificar en AWS Glue y que, por lo tanto, Athena puede utilizar para la proyección de particiones.

### Procedimientos para personalizar la plantilla de ruta de partición
<a name="partition-projection-custom-s3-storage-locations"></a>

De forma predeterminada, Athena crea ubicaciones de partición utilizando el formulario `s3://amzn-s3-demo-bucket/<table-root>/partition-col-1=<partition-col-1-val>/partition-col-2=<partition-col-2-val>/`, pero si sus datos están organizados de manera diferente, Athena ofrece un mecanismo para personalizar esta plantilla de ruta. Para ver los pasos, consulte [Procedimientos para especificar ubicaciones de almacenamiento de S3 personalizadas](partition-projection-setting-up.md#partition-projection-specifying-custom-s3-storage-locations).

## Consideraciones y limitaciones
<a name="partition-projection-considerations-and-limitations"></a>

Tenga en cuenta las siguientes consideraciones:
+ La proyección de particiones elimina la necesidad de especificar particiones manualmente en AWS Glue o en un metaalmacén externo de Hive.
+ Cuando habilita la proyección de particiones en una tabla, Athena ignora los metadatos de partición en AWS Glue Data Catalog o el metaalmacén externo de Hive de esa tabla.
+ Si una partición proyectada no existe en Amazon S3, Athena seguirá proyectando la partición. Athena no arroja un error, pero no se devuelve ningún dato. Sin embargo, si hay demasiadas particiones vacías, el rendimiento puede ser más lento en comparación con las particiones de AWS Glue tradicionales. Si más de la mitad de las particiones proyectadas están vacías, se recomienda utilizar particiones tradicionales.
+ Las consultas de valores que están más allá de los límites de intervalos definidos para la proyección de particiones no devuelven ningún error. En su lugar, la consulta se ejecuta, pero devuelve cero filas. Por ejemplo, si tiene datos relacionados con el tiempo que comienzan en 2020 y se definen como `'projection.timestamp.range'='2020/01/01,NOW'`, una consulta como `SELECT * FROM table-name WHERE timestamp = '2019/02/02'` se completará correctamente, pero devolverá cero filas.
+ La proyección de particiones solo se puede utilizar cuando se consulta la tabla a través de Athena. Si se lee la misma tabla a través de otro servicio, como Amazon Redshift Spectrum, Athena para Spark o Amazon EMR, se utilizan los metadatos de partición estándar.
+ Dado que la proyección de particiones es una característica de solo DML, `SHOW PARTITIONS` no enumera las particiones proyectadas por Athena pero no registradas en el catálogo de AWS Glue o en el metaalmacén externo de Hive. 
+ Athena no utiliza las propiedades de tabla de vistas como configuración para la proyección de particiones. Para evitar esta limitación, configure y habilite la proyección de particiones en las propiedades de tabla para las tablas a las que hacen referencia las vistas.

## Video
<a name="partition-projection-video"></a>

En el siguiente video se muestra cómo utilizar la proyección de particiones para mejorar el rendimiento de las consultas en Athena.

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


**Topics**
+ [Información de la eliminación de particiones frente a la proyección de particiones](#partition-projection-pruning-vs-projection)
+ [Procedimientos para usar la proyección de particiones](#partition-projection-using)
+ [Algunos casos de uso](#partition-projection-use-cases)
+ [Consideraciones y limitaciones](#partition-projection-considerations-and-limitations)
+ [Video](#partition-projection-video)
+ [Configuración de la proyección de particiones](partition-projection-setting-up.md)
+ [Tipos admitidos para la proyección de particiones](partition-projection-supported-types.md)
+ [Uso de partición de ID dinámica](partition-projection-dynamic-id-partitioning.md)
+ [Ejemplo de Amazon Data Firehose](partition-projection-kinesis-firehose-example.md)

# Configuración de la proyección de particiones
<a name="partition-projection-setting-up"></a>

Configurar la proyección de particiones en las propiedades de una tabla es un proceso de dos pasos:

1. Especifique los intervalos de datos y los patrones relevantes para cada columna de partición, o utilice una plantilla personalizada.

1. Habilite la proyección de particiones para la tabla.

**nota**  
Antes de agregar propiedades de proyección de particiones a una tabla existente, la columna de partición para la que va a configurar las propiedades de proyección de particiones ya debe existir en el esquema de la tabla. Si la columna de partición aún no existe, debe agregar una columna de partición a la tabla existente manualmente. AWS Glue no realiza este paso automáticamente. 

En esta sección se muestra cómo establecer estas propiedades de tabla para AWS Glue. Para configurarlas, puede utilizar la consola de AWS Glue, las consultas [CREATE TABLE](create-table.md) de Athena o las operaciones de [AWS Glue API](https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api.html). El siguiente procedimiento muestra cómo establecer las propiedades en la consola de AWS Glue.

**: cómo configurar y habilitar la proyección de particiones mediante la consola de AWS Glue**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de AWS Glue en [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/).

1. Seleccione la pestaña **Tablas**.

   En la pestaña **Tablas** puede editar tablas existentes o elegir **Agregar tablas** para crear otras nuevas. Para obtener información sobre cómo agregar tablas manualmente o con un rastreador, consulte [Trabajo con tablas en la consola de AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/console-tables.html) en la *Guía para desarrolladores de AWS Glue*.

1. En la lista de tablas, elija el vínculo de la tabla que desea editar.  
![\[En la consola de AWS Glue, elija una tabla para editar.\]](http://docs.aws.amazon.com/es_es/athena/latest/ug/images/partition-projection-1.png)

1. Seleccione **Acciones**, **Editar la tabla**.

1. En la página **Editar la tabla**, en la sección **Propiedades de la tabla**, agregue el siguiente par de clave-valor en cada columna particionada:

   1. En **Clave**, añada `projection.columnName.type`.

   1. En **Valor**, añada uno de los tipos admitidos: `enum`, `integer`, `date`, o `injected`. Para obtener más información, consulte [Tipos admitidos para la proyección de particiones](partition-projection-supported-types.md).

1. Siguiendo las instrucciones de [Tipos admitidos para la proyección de particiones](partition-projection-supported-types.md), añada pares clave-valor adicionales de acuerdo con sus requisitos de configuración.

   La siguiente configuración de tabla de ejemplo configura la columna `year` para la proyección de particiones, lo que restringe los valores que se pueden devolver a un intervalo comprendido entre 2010 y 2016.  
![\[Configuración de la proyección de particiones para una columna de partición en las propiedades de la tabla de la consola de AWS Glue.\]](http://docs.aws.amazon.com/es_es/athena/latest/ug/images/partition-projection-3.png)

1. Añada un par clave-valor para habilitar la proyección de particiones. En **Clave**, escriba `projection.enabled`, y en su **Valor**, escriba `true`.
**nota**  
Puede deshabilitar la proyección de particiones en esta tabla en cualquier momento estableciendo `projection.enabled` como `false`.

1. Cuando termine de actualizar las etiquetas, elija **Guardar**.

1. En el Editor de consultas de Athena, pruebe la consulta de las columnas que configuró para la tabla.

   La siguiente consulta de ejemplo utiliza `SELECT DISTINCT` para devolver los valores únicos de la columna `year`. La base de datos contiene datos de 1987 a 2016, pero la propiedad `projection.year.range` restringe los valores devueltos a los años 2010 a 2016.  
![\[Consultar una columna que utiliza la proyección de particiones.\]](http://docs.aws.amazon.com/es_es/athena/latest/ug/images/partition-projection-5.png)
**nota**  
Si establece `projection.enabled` como `true` pero no puede configurar una o más columnas de partición, recibirá un mensaje de error como el siguiente:  
`HIVE_METASTORE_ERROR: Table database_name.table_name is configured for partition projection, but the following partition columns are missing projection configuration: [column_name] (table database_name.table_name)`.

## Procedimientos para especificar ubicaciones de almacenamiento de S3 personalizadas
<a name="partition-projection-specifying-custom-s3-storage-locations"></a>

Al editar propiedades de tabla en AWS Glue, también puede especificar una plantilla de ruta de Amazon S3 personalizada para las particiones proyectadas. Una plantilla personalizada permite a Athena asignar correctamente valores de partición a ubicaciones de archivos de Amazon S3 personalizadas que no siguen un patrón `.../column=value/...` típico. 

El uso de una plantilla personalizada es opcional. Sin embargo, si utiliza una plantilla personalizada, la plantilla debe contener un marcador de posición para cada columna de partición. Las ubicaciones con plantilla deben terminar con una barra diagonal para que los archivos de datos particionados se alojen en una “carpeta” por partición.

**Para especificar una plantilla de ubicación de partición personalizada**

1. Siguiendo los pasos para [configurar y habilitar la proyección de particiones mediante la consola de AWS Glue](#partition-projection-setting-up-procedure), agregue un par clave-valor adicional que especifique una plantilla personalizada de la siguiente manera:

   1. En **Clave**, escriba `storage.location.template`.

   1. En **Valor**, especifique una ubicación que incluya un marcador de posición para cada columna de partición. Asegúrese de que cada marcador de posición (y la ruta de S3 en sí) termine con una sola barra diagonal.

      En los siguientes valores de plantilla de ejemplo se asume una tabla con columnas de partición `a`, `b` y `c`.

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/${c}/      
      ```

      ```
      s3://amzn-s3-demo-bucket/table_root/c=${c}/${b}/some_static_subdirectory/${a}/${b}/${c}/${c}/      
      ```

      En la misma tabla, el siguiente valor de plantilla de ejemplo no es válido porque no contiene marcador de posición para la columna `c`.

      ```
      s3://amzn-s3-demo-bucket/table_root/a=${a}/${b}/some_static_subdirectory/         
      ```

1. Seleccione **Aplicar**.

# Tipos admitidos para la proyección de particiones
<a name="partition-projection-supported-types"></a>

Una tabla puede tener cualquier combinación de tipos de columna de partición `enum`, `integer`, `date,` o `injected`.

## Tipo enum
<a name="partition-projection-enum-type"></a>

Utilice el tipo `enum` para las columnas de partición cuyos valores sean miembros de un conjunto enumerado (por ejemplo, códigos de aeropuerto o Regiones de AWS).

Defina las propiedades de partición en la tabla de la siguiente manera:


****  

| Nombre de la propiedad | Valores de ejemplo | Descripción | 
| --- | --- | --- | 
| projection.columnName.type |  `enum`  | Obligatorio. El tipo de proyección que se va a utilizar en la columna columnName. El valor debe ser enum (sin distinción mayúsculas y minúsculas) para indicar el uso del tipo enum. Se permite un espacio en blanco inicial y final. | 
| projection.columnName.values |  `A,B,C,D,E,F,G,Unknown`  | Obligatorio. Lista separada por comas de los valores de partición enumerados para la columna columnName. Cualquier espacio en blanco se considera parte de un valor enum. | 

**nota**  
Como práctica recomendada, sugerimos limitar el uso de proyecciones de partición basadas en `enum` a unas pocas docenas o menos. Si bien no hay un límite específico para las proyecciones `enum`, el tamaño total de los metadatos de la tabla no puede superar el límite de AWS Glue de aproximadamente 1 MB cuando se comprime a gzip. Tenga en cuenta que este límite se comparte entre partes clave de la tabla, como nombres de columna, ubicación, formato de almacenamiento y otros. Si utiliza más de unas cuantas docenas de identificadores únicos en la proyección `enum`, considere un enfoque alternativo, como la asignación de buckets en un número menor de valores únicos en un campo sustituto. Al intercambiar cardinalidad, puede controlar el número de valores únicos en `enum`. 

## Tipo entero
<a name="partition-projection-integer-type"></a>

Utilice el tipo entero para las columnas de partición cuyos valores posibles sean interpretables como enteros dentro de un intervalo definido. Las columnas enteras proyectadas se limitan actualmente al intervalo de un Java con signo largo (-263 a 263-1 inclusive).


****  

| Nombre de la propiedad | Valores de ejemplo | Descripción | 
| --- | --- | --- | 
| projection.columnName.type |  `integer`  | Obligatorio. El tipo de proyección que se va a utilizar en la columna columnName. El valor debe ser integer (sin distinción entre mayúsculas y minúsculas) para indicar el uso del tipo entero. Se permite un espacio en blanco inicial y final. | 
| projection.columnName.range |  `0,10` `-1,8675309` `0001,9999`  | Obligatorio. Lista separada por comas de dos elementos que proporciona los valores de intervalo mínimo y máximo que deben devolver las consultas de la columna columnName. Tenga en cuenta que los valores deben estar separados por una coma, no por un guion. Estos valores son inclusivos, pueden ser negativos y pueden tener ceros a la izquierda. Se permite un espacio en blanco inicial y final. | 
| projection.columnName.interval |  `1` `5`  | Opcional. Un entero positivo que especifica el intervalo entre los valores de partición sucesivos en la columna columnName. Por ejemplo, un valor range de “1,3” con un valor interval de “1” produce los valores 1, 2 y 3. El mismo valor range con un valor interval de “2” produce los valores 1 y 3, omitiendo 2. Se permite un espacio en blanco inicial y final. El valor predeterminado es 1. | 
| projection.columnName.digits |  `1` `5`  | Opcional. Un entero positivo que especifica el número de dígitos que se incluirán en la representación final del valor de partición de la columna columnName. Por ejemplo, un valor de range de “1,3” que tiene un valor de digits de “1” produce los valores 1, 2 y 3. El mismo valor de range con un valor de digits de “2” produce los valores 01, 02 y 03. Se permite un espacio en blanco inicial y final. Por defecto, no hay número estático de dígitos ni ceros a la izquierda. | 

## Tipo de fecha
<a name="partition-projection-date-type"></a>

Utilice el tipo de fecha para las columnas de partición cuyos valores se pueden interpretar como fechas (con horas opcionales) dentro de un rango definido.

**importante**  
Las columnas de fecha proyectada se generan en hora universal coordinada (UTC) en el momento de ejecución de la consulta.


****  

| Nombre de la propiedad | Valores de ejemplo | Descripción | 
| --- | --- | --- | 
| projection.columnName.type |  `date`  | Obligatorio. El tipo de proyección que se va a utilizar en la columna columnName. El valor debe ser date (sin distinción entre mayúsculas y minúsculas) para indicar el uso del tipo de fecha. Se permite un espacio en blanco inicial y final. | 
| projection.columnName.range |  `201701,201812` `01-01-2010,12-31-2018` `NOW-3YEARS,NOW` `201801,NOW+1MONTH`  |  Obligatorio. Lista separada por comas de dos elementos que proporciona los valores `range` mínimo y máximo de la columna *columnName*. Estos valores son inclusivos y pueden utilizar cualquier formato compatible con los tipos de fechas `java.time.*` de Java. Tanto los valores mínimo como máximo deben utilizar el mismo formato. El formato especificado en la propiedad `.format` debe ser el formato utilizado para estos valores. Esta columna también puede contener cadenas de fecha relativas, con el formato de este patrón de expresión regular: `\s*NOW\s*(([\+\-])\s*([0-9]+)\s*(YEARS?\|MONTHS?\|WEEKS?\|DAYS?\|HOURS?\|MINUTES?\|SECONDS?)\s*)?` Se permiten espacios en blanco, pero los literales de fecha se consideran parte de las cadenas de fecha.  | 
| projection.columnName.format |  `yyyyMM` `dd-MM-yyyy` `dd-MM-yyyy-HH-mm-ss`  | Obligatorio. Una cadena de formato de fecha basada en el formato de fecha Java [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html). Puede ser cualquier tipo de Java.time.\$1 compatible. | 
| projection.columnName.interval |  `1` `5`  |  Un entero positivo que especifica el intervalo entre los valores de partición sucesivos de la columna *columnName*. Por ejemplo, un valor de `range` de `2017-01,2018-12` con un valor de `interval` de `1` y un valor de `interval.unit` de `MONTHS` produce los valores 2017-01, 2017-02, 2017-03, etc. El mismo valor de `range` con un valor de `interval` de `2` y un valor de `interval.unit` de `MONTHS` produce los valores 2017-01, 2017-03, 2017-05, etc. Se permite un espacio en blanco inicial y final. Cuando las fechas proporcionadas tienen una precisión de un solo día o de un mes, la `interval` es opcional y el valor predeterminado es 1 día o 1 mes, respectivamente. De lo contrario, se requiere el `interval`.  | 
| projection.columnName.interval.unit |  `YEARS` `MONTHS` `WEEKS` `DAYS` `HOURS` `MINUTES` `SECONDS` `MILLIS`  |  Palabra de unidad de tiempo que representa la forma serializada de una [ChronoUnit](https://docs.oracle.com/javase/8/docs/api/java/time/temporal/ChronoUnit.html). Los valores posibles son `YEARS`, `MONTHS`, `WEEKS`, `DAYS`, `HOURS`, `MINUTES`, `SECONDS` o `MILLIS`. Los valores no distinguen entre mayúsculas y minúsculas. Cuando las fechas proporcionadas tienen una precisión de un solo día o de un mes, la `interval.unit` es opcional y el valor predeterminado es 1 día o 1 mes, respectivamente. De lo contrario, se requiere la `interval.unit`.  | 

**Example – Partición por mes**  
La siguiente tabla de configuración de ejemplo divide los datos por mes desde 2015 hasta la actualidad.  

```
'projection.month.type'='date', 
'projection.month.format'='yyyy-MM', 
'projection.month.interval'='1', 
'projection.month.interval.unit'='MONTHS', 
'projection.month.range'='2015-01,NOW', 
...
```

## Tipo inyectado
<a name="partition-projection-injected-type"></a>

Utilice el tipo inyectado para columnas de partición con valores posibles que no se pueden generar procesalmente dentro de algún intervalo lógico pero que se proporcionan en una cláusula `WHERE` de la consulta como un solo valor.

Es importante tener en cuenta los siguientes puntos:
+ Las consultas sobre columnas inyectadas fallan si no se proporciona una expresión de filtro para cada columna inyectada.
+ Las consultas con múltiples valores para una expresión de filtro en una columna inyectada solo funcionan si los valores están separados.
+ Solo se admiten las columnas de tipo `string`.
+ Cuando utiliza la cláusula `WHERE IN` con una columna de partición inyectada, hay un límite de 1000 valores que se pueden especificar en la lista `IN`. Para consultar un conjunto de datos con más de 1000 particiones para una columna inyectada, divida la consulta en múltiples consultas más pequeñas, cada una con hasta 1000 valores en la cláusula `WHERE IN`, y luego agregue los resultados.


****  

| Nombre de la propiedad | Valor | Descripción | 
| --- | --- | --- | 
| projection.columnName.type |  `injected`  | Obligatorio. El tipo de proyección que se va a utilizar en la columna columnName. Solo se admite el tipo string. El valor especificado debe ser injected (sin distinción entre mayúsculas y minúsculas). Se permite un espacio en blanco inicial y final. | 

Para obtener más información, consulte [Cuándo usar el tipo de proyección de `injected`](partition-projection-dynamic-id-partitioning.md#partition-projection-injection).

# Uso de partición de ID dinámica
<a name="partition-projection-dynamic-id-partitioning"></a>

Si los datos están divididos por una propiedad con cardinalidad alta o cuando los valores no se pueden conocer de antemano, puede utilizar el tipo de proyección `injected`. Algunos ejemplos de estas propiedades son los nombres de usuario y los ID de dispositivos o productos. Cuando se utiliza el tipo de proyección `injected` para configurar una clave de partición, Athena utiliza los valores de la propia consulta para calcular el conjunto de particiones que se leerán.

Para que Athena pueda ejecutar una consulta en una tabla que tenga una clave de partición configurada con el tipo de proyección `injected`, debe cumplirse lo siguiente:
+ La consulta debe incluir al menos un valor para la clave de partición.
+ Los valores deben ser literales o expresiones que se puedan evaluar sin leer ningún dato.

Si no se cumple alguno de estos criterios, la consulta fallará y mostrará el siguiente error:

CONSTRAINT\$1VIOLATION: En el caso de la columna de partición proyectada inyectada *column\$1name*, la cláusula WHERE debe contener únicamente condiciones de igualdad estáticas, y al menos una de estas condiciones debe estar presente.

## Cuándo usar el tipo de proyección de `injected`
<a name="partition-projection-injection"></a>

Imagine que tiene un conjunto de datos que consta de eventos de dispositivos de IoT, particionados en los ID de los dispositivos. Este conjunto de datos incluye las siguientes características:
+ Los ID de los dispositivos se generan de forma aleatoria.
+ Los dispositivos nuevos se aprovisionan con frecuencia.
+ Actualmente, hay cientos de miles de dispositivos y en el futuro habrá millones.

Este conjunto de datos es difícil de administrar con los metaalmacenes tradicionales. Es difícil mantener las particiones sincronizadas entre el almacenamiento de datos y el metaalmacén, y el filtrado de las particiones puede resultar ser lento durante la planificación de las consultas. Sin embargo, si configura una tabla para usar la proyección de particiones y usa el tipo de proyección `injected`, tiene dos ventajas: no tiene que administrar las particiones en el metaalmacén y sus consultas no tienen que buscar los metadatos de las particiones.

En el siguiente ejemplo de `CREATE TABLE`, se crea una tabla para el conjunto de datos de eventos del dispositivo que se acaba de describir. La tabla utiliza el tipo de proyección inyectada.

```
CREATE EXTERNAL TABLE device_events (
  event_time TIMESTAMP,
  data STRING,
  battery_level INT
)
PARTITIONED BY (
  device_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
  "projection.enabled" = "true",
  "projection.device_id.type" = "injected",
  "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${device_id}"
)
```

La siguiente consulta de ejemplo busca el número de eventos recibidos de tres dispositivos específicos en el transcurso de 12 horas.

```
SELECT device_id, COUNT(*) AS events
FROM device_events
WHERE device_id IN (
  '4a770164-0392-4a41-8565-40ed8cec737e',
  'f71d12cf-f01f-4877-875d-128c23cbde17',
  '763421d8-b005-47c3-ba32-cc747ab32f9a'
)
AND event_time BETWEEN TIMESTAMP '2023-11-01 20:00' AND TIMESTAMP '2023-11-02 08:00'
GROUP BY device_id
```

Al ejecutar esta consulta, Athena ve los tres valores de la clave de partición `device_id` y los usa para calcular las ubicaciones de las particiones. Athena utiliza el valor de la propiedad `storage.location.template` para generar las siguientes ubicaciones:
+ `s3://amzn-s3-demo-bucket/prefix/4a770164-0392-4a41-8565-40ed8cec737e`
+ `s3://amzn-s3-demo-bucket/prefix/f71d12cf-f01f-4877-875d-128c23cbde17`
+ `s3://amzn-s3-demo-bucket/prefix/763421d8-b005-47c3-ba32-cc747ab32f9a`

Si omite la propiedad `storage.location.template` en la configuración de proyección de la partición, Athena utiliza la partición tipo Hive para proyectar las ubicaciones de las particiones en función del valor de `LOCATION` (por ejemplo, `s3://amzn-s3-demo-bucket/prefix/device_id=4a770164-0392-4a41-8565-40ed8cec737e`).

# Ejemplo de Amazon Data Firehose
<a name="partition-projection-kinesis-firehose-example"></a>

Cuando se usa Firehose para entregar datos a Amazon S3, la configuración predeterminada escribe objetos con claves que se parecen al siguiente ejemplo:

```
s3://amzn-s3-demo-bucket/prefix/yyyy/MM/dd/HH/file.extension
```

Para crear una tabla de Athena que encuentre las particiones de forma automática en el momento de la consulta, en lugar de tener que agregarlas al catálogo de datos de AWS Glue Data Catalog a medida que llegan nuevos datos, puede usar la proyección de particiones.

En el siguiente ejemplo de `CREATE TABLE` se usa la configuración predeterminada de Firehose.

```
CREATE EXTERNAL TABLE my_ingested_data (
 ...
)
...
PARTITIONED BY (
 datehour STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.datehour.type" = "date",
 "projection.datehour.format" = "yyyy/MM/dd/HH",
 "projection.datehour.range" = "2021/01/01/00,NOW",
 "projection.datehour.interval" = "1",
 "projection.datehour.interval.unit" = "HOURS",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${datehour}/"
)
```

La cláusula `TBLPROPERTIES` de la instrucción `CREATE TABLE` indica a Athena lo siguiente:
+ Usar la proyección de la partición al consultar la tabla
+ La clave de partición `datehour` es de tipo `date` (que incluye una hora opcional)
+ Cómo se formatean las fechas
+ El rango de fechas y horas. Tenga en cuenta que los valores deben estar separados por una coma, no por un guion.
+ Dónde encontrar los datos en Amazon S3.

Al consultar la tabla, Athena calcula los valores de `datehour` y usa la plantilla de ubicación de almacenamiento para generar una lista de ubicaciones de partición.

**Topics**
+ [Cómo usar el tipo `date`](partition-projection-kinesis-firehose-example-using-the-date-type.md)
+ [Cómo elegir las claves de partición](partition-projection-kinesis-firehose-example-choosing-partition-keys.md)
+ [Cómo utilizar los prefijos personalizados y las particiones dinámicas](partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning.md)

# Cómo usar el tipo `date`
<a name="partition-projection-kinesis-firehose-example-using-the-date-type"></a>

Cuando se usa el tipo `date` para una clave de partición proyectada, se debe especificar un rango. Como no tiene datos para fechas anteriores a la creación del flujo de entrega de Firehose, puede usar la fecha de creación como inicio. Y como no tiene datos para fechas en el futuro, puede usar el token especial `NOW` como fin.

En el ejemplo de `CREATE TABLE`, la fecha de inicio se especifica como 1 de enero de 2021 a medianoche UTC.

**nota**  
Configure un rango que se ajuste lo más posible a sus datos para que Athena busque solo las particiones existentes.

Cuando se ejecuta una consulta en la tabla de ejemplo, Athena usa las condiciones de la clave de partición `datehour` en combinación con el rango para generar valores. Analice la siguiente consulta:

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2020/12/15/00'
AND datehour < '2021/02/03/15'
```

La primera condición de la consulta `SELECT` usa una fecha que es anterior al inicio del rango de fechas especificado por la instrucción `CREATE TABLE`. Como la configuración de la proyección de la partición especifica que no hay particiones para las fechas anteriores al 1 de enero de 2021, Athena busca datos solo en las siguientes ubicaciones, e ignora las fechas anteriores a la consulta.

```
s3://amzn-s3-demo-bucket/prefix/2021/01/01/00/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/01/
s3://amzn-s3-demo-bucket/prefix/2021/01/01/02/
...
s3://amzn-s3-demo-bucket/prefix/2021/02/03/12/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/13/
s3://amzn-s3-demo-bucket/prefix/2021/02/03/14/
```

Del mismo modo, si la consulta se ejecuta en una fecha y hora anteriores al 3 de febrero de 2021 a las 15:00 h, la última partición reflejaría la fecha y hora actuales, no la fecha y hora de la condición de consulta.

Si quiere consultar los datos más recientes, puede aprovechar el hecho de que Athena no genera fechas futuras y especificar solo una `datehour` de inicio, como en el siguiente ejemplo.

```
SELECT *
FROM my_ingested_data
WHERE datehour >= '2021/11/09/00'
```

# Cómo elegir las claves de partición
<a name="partition-projection-kinesis-firehose-example-choosing-partition-keys"></a>

Puede especificar cómo la proyección de particiones asigna las ubicaciones de las particiones a las claves de partición. En el ejemplo de `CREATE TABLE` de la sección anterior, la fecha y la hora se han combinado en una clave de partición denominada datehour, pero se pueden usar otros esquemas. Por ejemplo, también podría configurar una tabla con claves de partición separadas para el año, el mes, el día y la hora. 

No obstante, si se dividen las fechas en año, mes y día no se puede utilizar el tipo de proyección de particiones `date`. Una alternativa es separar la fecha de la hora para seguir aprovechando el tipo de proyección de particiones `date`, pero realizar consultas que especifiquen intervalos de horas más fáciles de leer.

Con esto en mente, el siguiente ejemplo `CREATE TABLE` separa la fecha de la hora. Debido a que `date` es una palabra reservada en SQL, en el ejemplo se utiliza `day` como nombre para la clave de partición que representa la fecha.

```
CREATE EXTERNAL TABLE my_ingested_data2 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 hour INT
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy/MM/dd",
 "projection.day.range" = "2021/01/01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.hour.type" = "integer",
 "projection.hour.range" = "0,23",
 "projection.hour.digits" = "2",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${hour}/"
)
```

En la instrucción `CREATE TABLE` del ejemplo, la hora es una clave de partición independiente, configurada como un número entero. La configuración de la clave de partición de la hora especifica el rango de 0 a 23, y que la hora debe formatearse con dos dígitos cuando Athena genera las ubicaciones de la partición.

Una consulta para la tabla `my_ingested_data2` podría verse así:

```
SELECT *
FROM my_ingested_data2
WHERE day = '2021/11/09'
AND hour > 3
```

## Descripción de los tipos de datos de claves de particiones y proyección de particiones
<a name="partition-projection-kinesis-firehose-example-partition-key-types-and-partition-projection-types"></a>

Tenga en cuenta que la clave `datehour` en el primer ejemplo `CREATE TABLE` está configurada como `date` en la configuración de la proyección de particiones, pero el tipo de la clave de partición es `string`. Lo mismo ocurre con `day` en el segundo ejemplo. Los tipos de configuración de proyección de particiones solo le dicen a Athena cómo formatear los valores cuando genera las ubicaciones de las particiones. Los tipos que se especifican no cambian el tipo de la clave de partición: en las consultas, `datehour` y `day` son de tipo `string`.

Cuando una consulta incluye una condición como `day = '2021/11/09'`, Athena analiza la cadena a la derecha de la expresión con el formato de fecha especificado en la configuración de la proyección de particiones. Después de que Athena verifique que la fecha está dentro del rango configurado, usa de nuevo el formato de fecha para insertar la fecha como una cadena en la plantilla del almacén.

De forma similar, para una condición de consulta como `day > '2021/11/09'`, Athena analiza el lado derecho y genera una lista de todas las fechas coincidentes dentro del rango configurado. A continuación, usa el formato de fecha para insertar cada fecha en la plantilla de ubicación de almacenamiento para crear la lista de ubicaciones de partición.

Escribir la misma condición como día `day > '2021-11-09'` o día `day > DATE '2021-11-09'` no funciona. En el primer caso, el formato de la fecha no coincide (observe los guiones en lugar de las barras inclinadas), y en el segundo caso, los tipos de datos no coinciden.

# Cómo utilizar los prefijos personalizados y las particiones dinámicas
<a name="partition-projection-kinesis-firehose-example-using-custom-prefixes-and-dynamic-partitioning"></a>

Firehose puede configurarse con [prefijos personalizados](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html) y [partición dinámica](https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html). Mediante estas características, puede configurar las claves de Amazon S3 y establecer esquemas de partición más compatibles con su caso de uso. También puede usar la proyección de particiones con estos esquemas de partición y configurarlos en consecuencia.

Por ejemplo, puede usar la característica de prefijo personalizado para obtener claves de Amazon S3 que tengan fechas con formato ISO en lugar del esquema predeterminado `yyyy/MM/dd/HH`.

También puede combinar los prefijos personalizados con el particionamiento dinámico para extraer una propiedad como `customer_id` de los mensajes de Firehose, como en el siguiente ejemplo.

```
prefix/!{timestamp:yyyy}-!{timestamp:MM}-!{timestamp:dd}/!{partitionKeyFromQuery:customer_id}/
```

Con ese prefijo de Amazon S3, el flujo de entrega de Firehose escribiría objetos en claves como `s3://amzn-s3-demo-bucket/prefix/2021-11-01/customer-1234/file.extension`. Para una propiedad como `customer_id`, cuyos valores pueden no conocerse de antemano, se puede usar el tipo de proyección de particiones `injected` y usar una instrucción `CREATE TABLE` como la siguiente:

```
CREATE EXTERNAL TABLE my_ingested_data3 (
 ...
)
...
PARTITIONED BY (
 day STRING,
 customer_id STRING
)
LOCATION "s3://amzn-s3-demo-bucket/prefix/"
TBLPROPERTIES (
 "projection.enabled" = "true",
 "projection.day.type" = "date",
 "projection.day.format" = "yyyy-MM-dd",
 "projection.day.range" = "2021-01-01,NOW",
 "projection.day.interval" = "1",
 "projection.day.interval.unit" = "DAYS",
 "projection.customer_id.type" = "injected",
 "storage.location.template" = "s3://amzn-s3-demo-bucket/prefix/${day}/${customer_id}/"
)
```

Cuando se consulta una tabla que tiene una clave de partición de tipo `injected`, la consulta debe incluir un valor para esa clave de partición. Una consulta para la tabla `my_ingested_data3` podría verse así:

```
SELECT *
FROM my_ingested_data3
WHERE day BETWEEN '2021-11-01' AND '2021-11-30'
AND customer_id = 'customer-1234'
```

## Uso del tipo DATE para la clave de partición diaria
<a name="partition-projection-kinesis-firehose-example-iso-formatted-dates"></a>

Ya que los valores de la clave de partición `day` tienen formato ISO, también puede usar el tipo `DATE` para la clave de partición del día en lugar de `STRING`, como en el siguiente ejemplo:

```
PARTITIONED BY (day DATE, customer_id STRING)
```

Cuando se consulta, esta estrategia permite usar las funciones de fecha en la clave de partición sin analizar ni iniciar, como en el siguiente ejemplo:

```
SELECT *
FROM my_ingested_data3
WHERE day > CURRENT_DATE - INTERVAL '7' DAY
AND customer_id = 'customer-1234'
```

**nota**  
Al especificar una clave de partición del tipo `DATE`, se supone que ha utilizado la característica de [prefijo personalizado](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html) para crear claves de Amazon S3 con fechas con formato ISO. Si utiliza el formato predeterminado de Firehose de `yyyy/MM/dd/HH`, debe especificar la clave de partición como tipo `string` aunque la propiedad de la tabla correspondiente sea de tipo `date`, como en el siguiente ejemplo:  

```
PARTITIONED BY ( 
  `mydate` string)
TBLPROPERTIES (
  'projection.enabled'='true', 
   ...
  'projection.mydate.type'='date',
  'storage.location.template'='s3://amzn-s3-demo-bucket/prefix/${mydate}')
```

# Evitar la limitación de Amazon S3
<a name="performance-tuning-s3-throttling"></a>

La limitación es el proceso de limitar la velocidad a la que se utiliza un servicio, una aplicación o un sistema. En AWS, se puede utilizar la limitación para evitar el uso excesivo del servicio Amazon S3 y aumentar la disponibilidad y la capacidad de respuesta de Amazon S3 para todos los usuarios. Sin embargo, dado que la limitación limita la velocidad a la que se pueden transferir los datos hacia Amazon S3 o desde este, es importante considerar la posibilidad de evitar que se limiten las interacciones.

Como se señaló en el capítulo sobre el [ajuste del rendimiento](performance-tuning.md), las optimizaciones pueden depender de las decisiones para cada servicio, de la forma en que se estructuran las tablas y los datos y de la forma en que se escriben las consultas.

**Topics**
+ [Reduzca las limitaciones a nivel de servicio](performance-tuning-s3-throttling-reduce-throttling-at-the-service-level.md)
+ [Optimización de las tablas](performance-tuning-s3-throttling-optimizing-your-tables.md)
+ [Optimización de las consultas](performance-tuning-s3-throttling-optimizing-queries.md)

# Reduzca las limitaciones a nivel de servicio
<a name="performance-tuning-s3-throttling-reduce-throttling-at-the-service-level"></a>

Para evitar que Amazon S3 se limite a nivel de servicio, puede supervisar el uso y ajustar las [cuotas de servicio](https://docs.aws.amazon.com/general/latest/gr/s3.html#limits_s3), o bien utilizar determinadas técnicas, como las particiones. A continuación, se detallan algunas de las condiciones que pueden provocar la limitación:
+ **Superar los límites de solicitudes de la API de su cuenta**: Amazon S3 tiene límites de solicitudes de API predeterminados que se basan en el tipo de cuenta y el uso. Si supera el número máximo de solicitudes por segundo para un solo prefijo, es posible que sus solicitudes se limiten para evitar la sobrecarga del servicio Amazon S3.
+ **Partición insuficiente de los datos**: si no particiona correctamente los datos y transfiere una gran cantidad de datos, Amazon S3 puede limitar sus solicitudes. Para obtener más información sobre las particiones, consulte la sección [Utilice particiones](performance-tuning-s3-throttling-optimizing-your-tables.md#performance-tuning-s3-throttling-use-partitioning) mencionada en este documento.
+ **Gran cantidad de objetos pequeños**: si es posible, evite tener una gran cantidad de archivos pequeños. Amazon S3 tiene un límite de [5500 solicitudes GET](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html) por segundo por prefijo particionado y las consultas de Athena tienen este mismo límite. Si analiza millones de objetos pequeños en una sola consulta, Amazon S3 puede limitar la consulta.

Para evitar un análisis excesivo, utilice ETL de AWS Glue para compactar periódicamente los archivos o particionar la tabla y agregar filtros de clave de partición. Para obtener más información, consulte los siguientes recursos.
+ [¿Cómo puedo configurar un trabajo de ETL en AWS Glue para generar archivos más grandes?](https://aws.amazon.com/premiumsupport/knowledge-center/glue-job-output-large-files/) (*AWS Centro de conocimientos de*)
+ [Lectura de archivos de entrada en grupos más grandes](https://docs.aws.amazon.com/glue/latest/dg/grouping-input-files.html) (*Guía para desarrolladores de AWS Glue*)

# Optimización de las tablas
<a name="performance-tuning-s3-throttling-optimizing-your-tables"></a>

Si tiene problemas de limitación, es importante que estructure los datos. Si bien Amazon S3 puede gestionar grandes cantidades de datos, a veces se produce una limitación debido a la forma en que están estructurados los datos.

En las siguientes secciones se ofrecen algunas sugerencias sobre cómo estructurar los datos en Amazon S3 para evitar problemas de limitación.

## Utilice particiones
<a name="performance-tuning-s3-throttling-use-partitioning"></a>

Puede utilizar las particiones para reducir la limitación al limitar la cantidad de datos a los que se puede acceder en cualquier momento. Al dividir los datos en columnas específicas, puede distribuir las solicitudes de manera uniforme entre varios objetos y reducir el número de solicitudes de un solo objeto. Al reducir la cantidad de datos que se deben analizar, el rendimiento de las consultas mejora y los costos se reducen.

Al crear una tabla, puede definir particiones, que actúan como columnas virtuales. Para crear una tabla con particiones en una instrucción `CREATE TABLE`, utilice la cláusula `PARTITIONED BY (column_name data_type)` a fin de definir las claves para dividir los datos.

Para restringir las particiones analizadas en una consulta, puede especificarlas como predicados en una cláusula `WHERE` de la consulta. De esta manera, las columnas que se utilizan con frecuencia como filtros son buenas candidatas para la creación de particiones. Una práctica común consiste en particionar los datos en función de intervalos de tiempo, lo que puede dar lugar a un esquema de particiones de varios niveles.

Tenga en cuenta que la creación de particiones también tiene un costo. Al aumentar el número de particiones de la tabla, también aumenta el tiempo necesario para recuperar y procesar los metadatos de las particiones. Por lo tanto, la sobrepartición puede eliminar los beneficios que se obtienen al particionar con un mejor criterio. Si sus datos están muy sesgados hacia un valor de partición y la mayoría de las consultas utilizan ese valor, es posible que incurra en una sobrecarga adicional.

Para obtener más información sobre la creación de particiones en Athena, consulte [¿Qué es la creación de particiones?](ctas-partitioning-and-bucketing-what-is-partitioning.md).

## Organice los datos en buckets
<a name="performance-tuning-s3-throttling-bucket-your-data"></a>

Otra forma de particionar los datos consiste en organizarlos en buckets en una sola partición. Al organizar los datos en buckets, especifica una o más columnas que contienen las filas que desea agrupar. A continuación, pone esas filas en varios buckets. De esta forma, solo consulta el bucket que debe leerse, lo que reduce el número de filas de datos que deben analizarse.

Al seleccionar una columna para utilizarla en los buckets, seleccione la columna que tenga una cardinalidad alta (es decir, que tenga muchos valores distintos), que esté distribuida de manera uniforme y que se utilice con frecuencia para filtrar los datos. Un ejemplo de una buena columna que se puede usar para organizar datos en buckets es una clave principal, como una columna de ID.

Para obtener más información acerca de la asignación de buckets en Athena, consulte [¿Qué es la asignación de buckets?](ctas-partitioning-and-bucketing-what-is-bucketing.md).

## Utilice índices de particiones de AWS Glue
<a name="performance-tuning-s3-throttling-use-aws-glue-partition-indexes"></a>

Puede usar índices de partición de AWS Glue para organizar los datos de una tabla en función de los valores de una o más particiones. Los índices de partición de AWS Glue pueden reducir el número de transferencias de datos, la cantidad de procesamiento de datos y el tiempo de procesamiento de las consultas.

Un índice de particiones de AWS Glue es un archivo de metadatos que contiene información sobre las particiones de la tabla, incluidas las claves de partición y sus valores. El índice de particiones se almacena en un bucket de Amazon S3 y AWS Glue lo actualiza automáticamente a medida que se agregan nuevas particiones a la tabla.

Cuando un índice de particiones de AWS Glue está presente, las consultas pueden recuperar un subconjunto de las particiones en lugar de cargar todas las particiones de la tabla. Las consultas solo se ejecutan en el subconjunto de datos que es relevante para la consulta.

Al crear una tabla en AWS Glue, puede crear un índice de particiones en cualquier combinación de claves de partición definidas en la tabla. Tras crear uno o más índices de partición en una tabla, debe agregar una propiedad a la tabla que permita el filtrado de particiones. A continuación, puede consultar la tabla desde Athena.

Para obtener información acerca de cómo crear índices de particiones en AWS Glue, consulte [Trabajar con índices de partición en AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html) en la *Guía para desarrolladores de AWS Glue*. Para obtener información sobre cómo agregar una propiedad de tabla para habilitar el filtrado de particiones, consulte [Optimización de las consultas con indexación y filtrado de particiones de AWS Glue](glue-best-practices-partition-index.md).

## Utilice la compresión de datos y la división de archivos
<a name="performance-tuning-s3-throttling-use-data-compression-and-file-splitting"></a>

La compresión de datos puede acelerar de forma significativa las consultas si los archivos tienen el tamaño óptimo o si se pueden dividir en grupos lógicos. Por lo general, las relaciones de compresión más altas requieren más ciclos de CPU para comprimir y descomprimir los datos. Para Athena, se recomienda utilizar Apache Parquet o Apache ORC, que comprimen los datos de forma predeterminada. Para obtener información sobre la compresión de datos en Athena, consulte [Uso de la compresión en Athena](compression-formats.md).

La división de archivos aumenta el paralelismo al permitir que Athena distribuya la tarea de leer un solo archivo entre varios lectores. Si un único archivo no se puede dividir, solo un único lector puede leerlo mientras los demás lectores permanecen inactivos. Apache Parquet y Apache ORC también admiten la división de archivos.

## Utilice almacenes de datos en columnas optimizados
<a name="performance-tuning-s3-throttling-use-optimized-columnar-data-stores"></a>

El rendimiento de las consultas de Athena mejora de forma significativa si convierte los datos a un formato de columnas. Al generar archivos en columnas, una técnica de optimización a tener en cuenta es ordenar los datos en función de la clave de partición.

Apache Parquet y Apache ORC son almacenes de datos en columnas de código abierto cuyo uso está generalizado. Para obtener información sobre cómo convertir un origen de datos de Amazon S3 existente a uno de estos formatos, consulte [Conversión a formatos de columnas](columnar-storage.md#convert-to-columnar).

### Utilice un tamaño de bloque de Parquet o de banda de ORC más grande
<a name="performance-tuning-s3-throttling-use-a-larger-parquet-block-size-or-orc-stripe-size"></a>

Parquet y ORC tienen parámetros de almacenamiento de datos que puede ajustar para su optimización. En Parquet, puede optimizar el tamaño del bloque. En ORC, puede optimizar el tamaño de las bandas. Cuanto más grande sea el bloque o la banda, más filas podrá almacenar en cada uno. De forma predeterminada, el tamaño del bloque de Parquet es de 128 MB y el tamaño de la banda de ORC es de 64 MB.

Si una banda de ORC ocupa menos de 8 MB (el valor predeterminado de `hive.orc.max_buffer_size`), Athena lee toda la banda de ORC. Esta es la compensación que Athena hace entre la selectividad de columnas y las operaciones de entrada/salida por segundo para bandas más pequeñas.

Si tiene tablas con un gran número de columnas, un tamaño de bloque o banda pequeño puede provocar que se analicen más datos de los necesarios. En estos casos, un tamaño de bloque más grande puede ser más eficiente.

### Utilice ORC para tipos complejos
<a name="performance-tuning-s3-throttling-use-orc-for-complex-types"></a>

Actualmente, cuando se consultan columnas almacenadas en Parquet con tipos de datos complejos (por ejemplo, `array`, `map` o `struct`), Athena lee toda una fila de datos, en lugar de leer solo de manera selectiva las columnas especificadas. Este es un problema conocido en Athena. Como solución, considere usar ORC.

### Elija un algoritmo de compresión
<a name="performance-tuning-s3-throttling-choose-a-compression-algorithm"></a>

Otro parámetro que puede configurar es el algoritmo de compresión de los bloques de datos. Para obtener información sobre los algoritmos de compresión compatibles con Parquet y ORC en Athena, consulte [Compatibilidad con la compresión de Athena](https://docs.aws.amazon.com/athena/latest/ug/compression-formats.html).

Para obtener más información sobre la optimización de los formatos de almacenamiento en columnas en Athena, consulte la sección “Optimizar la generación de almacenes de datos en columnas” en la publicación del Blog de macrodatos de AWS [Top 10 Performance Tuning Tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/) (Los 10 mejores consejos para ajustar el rendimiento de Amazon Athena).

## Utilice tablas de Iceberg
<a name="performance-tuning-s3-throttling-use-iceberg-tables"></a>

Apache Iceberg es un formato de tabla de código abierto para conjuntos de datos analíticos de gran tamaño diseñado para el uso optimizado en Amazon S3. Puede usar tablas de Iceberg para ayudar a reducir las limitaciones en Amazon S3.

Las tablas de Iceberg ofrecen las siguientes ventajas:
+ Puede dividir las tablas de Iceberg en una o más columnas. Esto optimiza el acceso a los datos y reduce la cantidad de datos que se deben analizar en las consultas.
+ Como el modo de almacenamiento de objetos de Iceberg optimiza las tablas de Iceberg para que funcionen con Amazon S3, puede procesar grandes volúmenes de datos y cargas de trabajo de consultas pesadas.
+ Las tablas de Iceberg en el modo de almacenamiento de objetos son escalables, tolerantes a errores y duraderas, lo que puede ayudar a reducir las limitaciones.
+ La compatibilidad con transacciones ACID significa que varios usuarios pueden agregar y eliminar objetos de Amazon S3 de forma atómica.

Para obtener más información sobre Apache Iceberg, consulte [Apache Iceberg](https://iceberg.apache.org/). Para obtener información acerca del uso de tablas de Apache Iceberg en Athena, consulte [Utilización de tablas de Iceberg](https://docs.aws.amazon.com/athena/latest/ug/querying-iceberg.html).

# Optimización de las consultas
<a name="performance-tuning-s3-throttling-optimizing-queries"></a>

Utilice las sugerencias de esta sección para optimizar sus consultas SQL en Athena.

## Utilice LIMIT con la cláusula ORDER BY
<a name="performance-tuning-s3-throttling-use-limit-with-the-order-by-clause"></a>

La cláusula `ORDER BY` devuelve los datos en un orden clasificado Esto requiere que Athena envíe todas las filas de datos a un único nodo de trabajo y luego las ordene. Este tipo de consulta puede ejecutarse durante mucho tiempo o, incluso, fallar.

Para aumentar la eficacia de las consultas, observe los valores *N* en la parte superior o inferior y utilice también una cláusula `LIMIT`. Esto reduce de forma significativa el costo de la clasificación, ya que tanto la clasificación como la limitación recaen en nodos de trabajo individuales en lugar de en un solo trabajo.

## Optimice las cláusulas JOIN
<a name="performance-tuning-s3-throttling-optimize-join-clauses"></a>

Al unir dos tablas, Athena distribuye la tabla de la derecha entre los nodos de trabajo y luego incluye la tabla de la izquierda para realizar la unión.

Por este motivo, especifique la tabla más grande en el lado izquierdo de la unión y la tabla más pequeña en el lado derecho de la unión. De esta forma, Athena utiliza menos memoria y ejecuta la consulta con una latencia menor.

También tenga en cuenta los siguientes puntos:
+ Cuando utilice varios comandos `JOIN`, especifique las tablas de mayor a menor.
+ Evite las uniones cruzadas a menos que la consulta las requiera.

## Optimice las cláusulas GROUP BY
<a name="performance-tuning-s3-throttling-optimize-group-by-clauses"></a>

El operador `GROUP BY` distribuye las filas en función de las columnas `GROUP BY` a los nodos de trabajo. Se hace referencia a estas columnas en la memoria y los valores se comparan a medida que se ingieren las filas. Los valores se agregan cuando la columna `GROUP BY` coincide. Teniendo en cuenta la forma en que funciona este proceso, se recomienda ordenar las columnas desde la cardinalidad más alta hasta la más baja.

## Utilice números en lugar de cadenas
<a name="performance-tuning-s3-throttling-use-numbers-instead-of-strings"></a>

Como los números requieren menos memoria y son más rápidos de procesar en comparación con las cadenas, utilice números en lugar de cadenas siempre que sea posible.

## Limite el número de columnas
<a name="performance-tuning-s3-throttling-limit-the-number-of-columns"></a>

A fin de reducir la cantidad total de memoria necesaria para almacenar los datos, limite el número de columnas especificado en la instrucción `SELECT`.

## Utilice expresiones comunes en lugar de LIKE
<a name="performance-tuning-s3-throttling-use-regular-expressions-instead-of-like"></a>

Las consultas que incluyen cláusulas como `LIKE '%string%'` en cadenas grandes pueden ser muy exigentes desde el punto de vista computacional. Al filtrar varios valores en una columna de cadena, utilice la función [regexp\$1like()](https://trino.io/docs/current/functions/regexp.html#regexp_like) y una expresión común en su lugar. Esto resulta muy útil cuando se compara una lista larga de valores.

## Utilice la cláusula LIMIT
<a name="performance-tuning-s3-throttling-use-the-limit-clause"></a>

En lugar de seleccionar todas las columnas al ejecutar una consulta, utilice la cláusula `LIMIT` para devolver solo las columnas que necesite. Esto reduce el tamaño del conjunto de datos que se procesa a través de la canalización de ejecución de la consulta. Las cláusulas `LIMIT` son más útiles cuando se consultan tablas que tienen un gran número de columnas basadas en cadenas. Las cláusulas `LIMIT` también son útiles cuando se realizan múltiples uniones o agregaciones en cualquier consulta.

# Recursos adicionales de
<a name="performance-tuning-additional-resources"></a>

Para obtener información adicional acerca del ajuste de rendimiento en Athena, tenga en cuenta los siguientes recursos:
+ Publicación en AWS Big Data Blog: [Top 10 performance tuning tips for Amazon Athena](https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-tips-for-amazon-athena/).
+ Publicación en AWS Big Data Blog: [Run queries 3x faster with up to 70% cost savings on the latest Amazon Athena engine](https://aws.amazon.com/blogs/big-data/run-queries-3x-faster-with-up-to-70-cost-savings-on-the-latest-amazon-athena-engine/) en *AWS Big Data Blog*.
+ Publicación en AWS Big Data Blog: [Improve federated queries with predicate pushdown in Amazon Athena](https://aws.amazon.com/blogs/big-data/improve-federated-queries-with-predicate-pushdown-in-amazon-athena/).
+ Guía del usuario de Amazon Simple Storage Service: [Prácticas recomendadas para patrones de diseño: optimizar el rendimiento de Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance.html).
+ Otras [publicaciones sobre Athena en AWS Big Data Blog](https://aws.amazon.com/blogs/big-data/tag/amazon-athena/). 
+ Haga una pregunta en [AWS re:Post](https://repost.aws/tags/TA78iVOM7gR62_QqDe2-CmiA/amazon-athena) con la etiqueta **Amazon Athena**.
+ Consulte los [temas sobre Athena en el Centro de conocimientos de AWS](https://aws.amazon.com/premiumsupport/knowledge-center/#Amazon_Athena).
+ Póngase en contacto con AWS Support (en la Consola de administración de AWS, haga clic en **Soporte**, **Centro de asistencia**.