Cómo particionar tablas Delta en ELT para consultas rápidas
Esta guía muestra cómo particionar tablas Delta en ELT para mejorar el rendimiento de las consultas y reducir costes de lectura. Aprender a elegir la columna de partición, crear la tabla particionada y optimizar archivos evita problemas como muchos archivos pequeños y particiones desequilibradas.
Requisitos previos
- Acceso a un entorno que escriba/ejecute SQL sobre Delta (ej.: Databricks, Spark SQL).
- Datos brutos ya cargados en una tabla/área de staging (ej.: mydb.raw_events).
- Permisos para crear tablas y ejecutar OPTIMIZE/VACUUM (si procede).
Paso 1: Elegir la columna de partición adecuada
Por qué: una mala elección crea particiones con muchos o pocos archivos y empeora el rendimiento. Buenas prácticas: preferir columnas con cardinalidad moderada y uso frecuente en filtros (WHERE). Para datos temporales, usar fechas (por día, mes) es habitual en ELT.
-- Exemplos de colunas a avaliar
-- COUNT(*) grouped para ver cardinalidade
SELECT event_date, COUNT(*) AS cnt
FROM mydb.raw_events
GROUP BY event_date
ORDER BY event_date DESC
LIMIT 50;
Paso 2: Crear la tabla Delta particionada
Explicación: crear la tabla en formato Delta y declarar PARTITIONED BY. Aquí hacemos un CTAS (CREATE TABLE AS SELECT) para materializar event_date derivada de un timestamp.
CREATE TABLE mydb.events_partitioned
USING delta
PARTITIONED BY (event_date)
AS
SELECT *, to_date(event_ts) AS event_date
FROM mydb.raw_events;
Paso 3: Cargar datos incrementales en la tabla particionada
Explicación: para ELT es habitual hacer transformaciones en el SELECT e insertar. Antes de insertar, reparticiona el DataFrame/consulta por event_date para reducir archivos pequeños. En Spark SQL/Databricks puedes usar INSERT INTO con SELECT reparticionado vía spark API (ejemplo en PySpark) o SQL con hint.
-- SQL simples (si el engine controla la escritura):
INSERT INTO mydb.events_partitioned
SELECT *, to_date(event_ts) AS event_date
FROM mydb.raw_events_incremental;
-- Ejemplo PySpark para controlar número de archivos por partición:
df = spark.table('mydb.raw_events_incremental')
df = df.withColumn('event_date', to_date(col('event_ts')))
# Reparticionar por event_date para optimizar escritura por partición
df.repartition('event_date').write.format('delta').mode('append').saveAsTable('mydb.events_partitioned')
Paso 4: Compactar archivos y optimizar (compaction)
Problema común: muchos archivos pequeños por partición. Solución: compactar usando OPTIMIZE (Databricks) o escribir con coalesce antes de save. OPTIMIZE es útil en Delta para crear archivos más grandes y reducir overhead de metadata.
-- Ejemplo Databricks: optimizar por tabla y, opcionalmente, ZORDER para columnas de consulta
OPTIMIZE mydb.events_partitioned
WHERE event_date = '2026-07-01';
-- Agregar manualmente con repartition/coalesce (antes de escribir nueva carga)
df.repartition(1, 'event_date').write.format('delta').mode('overwrite').option('overwriteSchema','true').saveAsTable('mydb.events_partitioned')
Paso 5: Gestionar evolución de particiones y particiones nulas
Errores comunes: inserciones con event_date NULL crean directorios _delta_log inesperados o particiones con valor NULL. Tratar NULLs durante la transformación y, si cambias la granularidad (día→mes), crear nueva columna y backfill.
-- Filtrar o substituir NULLs
INSERT INTO mydb.events_partitioned
SELECT *, coalesce(to_date(event_ts), date('1970-01-01')) AS event_date
FROM mydb.raw_events_incremental;
-- Para cambiar partición (ej.: day -> month) se crea una nueva tabla y CTAS con new_month
CREATE TABLE mydb.events_by_month
USING delta
PARTITIONED BY (event_month)
AS SELECT *, date_format(event_date,'yyyy-MM') AS event_month FROM mydb.events_partitioned;
Verificar el resultado
Ejecutar queries y comandos de metadata para confirmar que las particiones existen, los archivos están compactados y las consultas usan filtros de partición.
-- Ver particiones existentes
SHOW PARTITIONS mydb.events_partitioned;
-- Ver detalle de la tabla Delta
DESCRIBE DETAIL mydb.events_partitioned;
-- Probar si el filtro usa solo una partición (EXPLAIN):
EXPLAIN SELECT COUNT(*) FROM mydb.events_partitioned WHERE event_date = '2026-07-01';
-- Verificar tamaño medio de archivos por partición (ejemplo simplificado)
SELECT event_date, SUM(size) as total_bytes, SUM(file_count) as files
FROM (DESCRIBE HISTORY mydb.events_partitioned) -- si el engine expone metadatos
GROUP BY event_date ORDER BY event_date DESC LIMIT 20;
Conclusión
Particionar tablas Delta en ELT mejora la latencia y reduce costes cuando se hace con una buena elección de columna, control de archivos y mantenimiento (OPTIMIZE/VACUUM). Próximos pasos: medir el impacto con consultas reales, automatizar la compactación y probar el cambio de granularidad. Consejo: empieza por particionar por día y monitoriza la distribución de archivos — ¿tienes dudas sobre qué granularidad usar para tu volumen?