Saltar al contenido

lección 6

Athena: SQL directo sobre tu data lake

Consultas SQL serverless sobre datos en S3. Partition pruning, formatos óptimos, coste por escaneo y cuándo elegir Athena vs Redshift.

55 min

Athena no está en el plan gratuito de LocalStack (es del plan Ultimate, $89/mes). Qué puedes hacer sin pagar: tres de los cuatro ejercicios de esta lección no necesitan un motor SQL — los workgroups, las named queries y el estimador de coste son API y aritmética. Con moto (pip install "moto[server]" y python -m moto.server -p 4566, gratis y sin cuenta, mismo endpoint_url) los haces enteros. El ejercicio 1 es distinto: en cualquier emulador gratuito start_query_execution devuelve SUCCEEDED sin ejecutar nada, y get_query_results da cero filas. No es un fallo tuyo — por eso el ejercicio 1 se valida por su lógica (el ciclo lanzar → sondear → recoger), no por sus resultados.

Athena es la respuesta a una pregunta que todo equipo de datos se ha hecho: "¿cómo hago SQL sobre mi data lake sin montar un clúster?" La respuesta es sorprendentemente simple: apuntas Athena a tus datos en S3, usas el esquema del Data Catalog de Glue, y lanzas consultas SQL estándar. No hay servidores que gestionar, no hay clústeres que dimensionar. Pagas $5 por cada TB escaneado. Nada más.

Athena está basada en Presto/Trino (motores de consultas distribuidas open source) y entiende SQL estándar con extensiones. Puedes hacer JOINs, CTEs, window functions — todo lo que aprendiste en las skills de SQL. La diferencia es que en vez de consultar una base de datos tradicional, estás consultando archivos en S3 directamente.

### El modelo de coste: pagas por lo que escaneas

Este es el concepto más importante de Athena: te cobran por la cantidad de datos que tu consulta ESCANEA, no por el tiempo que tarda ni por los resultados que devuelve. Si tu consulta escanea 100GB de datos, pagas $0.50 (a $5/TB). Si escanea 1TB, pagas $5. Esto tiene implicaciones ENORMES para el diseño de tu data lake:

  • Parquet/ORC vs CSV: los formatos columnares solo leen las columnas que necesitas. Un SELECT de 3 columnas en Parquet escanea 10x menos que en CSV.
  • Particionado: si filtras por fecha y tus datos están particionados por fecha, Athena solo escanea las particiones relevantes (partition pruning).
  • Compresión: datos comprimidos (Snappy, GZIP, ZSTD) escanean menos bytes = menos coste.
  • SELECT *: el enemigo mortal. Selecciona SOLO las columnas que necesitas.

Consejo de senior: un data lake bien diseñado en Parquet particionado puede ser 100x más barato de consultar con Athena que el mismo data lake en CSV sin particionar. He visto equipos pasar de $500/mes a $5/mes solo cambiando el formato a Parquet y añadiendo particiones por fecha. La optimización de formato es la primera inversión que deberías hacer.

### Tu primera consulta con Athena

1import boto3
2import time
3
4athena = boto3.client('athena', endpoint_url='http://localhost:4566',
5 aws_access_key_id='test', aws_secret_access_key='test',
6 region_name='eu-west-1')
7
8# Ejecutar una consulta SQL sobre la tabla del catálogo de Glue
9query = """
10SELECT customer_id, SUM(amount) as total_gastado
11FROM fashionstore.ventas
12WHERE order_date >= '2024-01-01'
13GROUP BY customer_id
14ORDER BY total_gastado DESC
15LIMIT 10
16"""
17
18# Athena es asíncrono: lanzas la query y luego recoges el resultado
19response = athena.start_query_execution(
20 QueryString=query,
21 QueryExecutionContext={'Database': 'fashionstore'},
22 ResultConfiguration={
23 'OutputLocation': 's3://fashionstore-datalake/athena-results/'
24 }
25)
26
27query_id = response['QueryExecutionId']
28print(f"Query lanzada: {query_id}")
29
30# Esperar a que termine (en producción usarías un poller más sofisticado)
31while True:
32 status = athena.get_query_execution(QueryExecutionId=query_id)
33 state = status['QueryExecution']['Status']['State']
34 if state in ('SUCCEEDED', 'FAILED', 'CANCELLED'):
35 break
36 time.sleep(1)
37
38if state == 'SUCCEEDED':
39 results = athena.get_query_results(QueryExecutionId=query_id)
40 for row in results['ResultSet']['Rows'][1:]: # Skip header
41 print([col.get('VarCharValue', '') for col in row['Data']])

Athena es asíncrono: start_query → poll status → get_results

### Partition pruning: la clave del ahorro

Si tus datos están en s3://bucket/ventas/year=2024/month=01/ y tu query filtra por year=2024 AND month=01, Athena SOLO escanea esa carpeta. No toca los datos de otros meses o años. Esto se llama "partition pruning" y puede reducir el escaneo (y el coste) en un 95% para consultas que filtran por la columna de partición.

1# CTAS: Crear tabla optimizada a partir de datos raw
2# Convierte CSV a Parquet particionado — la operación más útil de Athena
3ctas_query = """
4CREATE TABLE fashionstore.ventas_optimizada
5WITH (
6 format = 'PARQUET',
7 partitioned_by = ARRAY['year', 'month'],
8 external_location = 's3://fashionstore-datalake/analytics/ventas/'
9)
10AS SELECT
11 order_id,
12 customer_id,
13 amount,
14 order_date,
15 YEAR(order_date) as year,
16 MONTH(order_date) as month
17FROM fashionstore.ventas_raw
18"""
19print("CTAS convierte CSV → Parquet particionado en una sola operación")

CTAS (Create Table As Select) es la forma más fácil de optimizar datos para Athena

### Athena vs Redshift: cuándo elegir cada uno

  • Athena: consultas ad-hoc, exploración, pocos usuarios, data lake en S3, pago por uso.
  • Redshift: dashboards con muchas consultas concurrentes, queries repetitivas, necesidad de latencia baja y predecible.
  • Regla práctica: si lanzas < 50 queries/día → Athena. Si lanzas > 500 queries/día → Redshift.
  • Athena escala a cero (si no consultas, no pagas). Redshift tiene coste fijo por clúster.

En LocalStack, Athena tiene funcionalidad limitada. Las consultas pueden no ejecutarse completamente. Usa los ejercicios para practicar la API y la lógica, pero ten en cuenta que en AWS real el motor SQL es completo y potente.

El formato de los datos determina cuánto pagas — Parquet particionado es 100x más barato que CSV plano

Consejo de senior: configura un "workgroup" en Athena con un límite de escaneo por query (ejemplo: máximo 10GB por consulta). Así, si alguien lanza un SELECT * sobre una tabla de 5TB sin querer, la query se cancela antes de generar una factura absurda.

## ejercicios

[01]

Lanzar tu primera query con Athena

Escribe una función que lance una query SQL contra Athena, espere a que termine y retorne los resultados como una lista de diccionarios.

Cargando editor...
[02]

Estimador de coste de query Athena

Crea una función que estime el coste de una query basándose en el tamaño de los datos y el formato. El CFO quiere saber cuánto costaría lanzar diferentes queries sobre el data lake.

Cargando editor...
[03]

Configurar workgroup con límites de coste

Crea un workgroup en Athena con límite de escaneo por query (máx 10GB) para evitar consultas accidentalmente caras.

Cargando editor...
[04]

Biblioteca de queries guardadas

Crea una biblioteca de named queries en Athena con las consultas más frecuentes del equipo de analytics de FashionStore.

Cargando editor...

Regístrate para guardar tu progreso.

## comentarios

Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.

Inicia sesión para comentar y responder.

cargando comentarios...