Command Palette

Search for a command to run...

ES·EN

Nivel 3 · 30 min

Particionamiento

El particionamiento divide lógicamente una tabla grande en tablas hijas más pequeñas. PostgreSQL soporta tres estrategias: por rango (RANGE), por lista (LIST) y por hash (HASH). El objetivo principal es eliminar particiones irrelevantes en tiempo de planificación (partition pruning).

Tipos de Partición

RANGE particiona por valores contiguos —ideal para fechas: CREATE TABLE events PARTITION BY RANGE (created_at). LIST particiona por valores discretos —ideal para enum-like: PARTITION BY LIST (region). HASH distribuye uniformemente usando un divisor —útil para balancear escrituras cuando no hay criterio natural de rango.

Partition Pruning

El planificador excluye automáticamente particiones que no pueden contener las filas buscadas. Para que funcione, el WHERE debe incluir la clave de partición. EXPLAIN muestra ''Partitions removed: N''. Sin partition pruning, una tabla de 36 particiones mensuales accedería a las 36 cuando solo necesitás una.

Mantenimiento de Particiones

Crear particiones futuras con anticipación (cronjob mensual). Eliminar particiones viejas con DETACH PARTITION y DROP TABLE —extremadamente rápido porque no hay VACUUM row-by-row. Índices, constraints y triggers se definen en la tabla padre y se heredan automáticamente. ATTACH PARTITION valida constraints existentes —usá NOT VALID + VALIDATE separado para tablas grandes.

Puntos clave

  • Partition pruning solo funciona si el WHERE incluye la clave de partición —diseñá la clave alrededor de tus consultas más frecuentes.
  • DROP TABLE en una partición es instantáneo comparado con DELETE masivo, que genera dead tuples y requiere VACUUM.
  • El particionamiento no reemplaza índices —creá índices dentro de cada partición para acelerar búsquedas que no usan la clave de partición.

Code example

-- Tabla particionada por rango de fecha
CREATE TABLE events (
  id BIGSERIAL,
  tenant_id INT NOT NULL,
  event_type TEXT NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
) PARTITION BY RANGE (created_at);

-- Partición mensual
CREATE TABLE events_2026_04
  PARTITION OF events
  FOR VALUES FROM (''2026-04-01'') TO (''2026-05-01'');

-- Índice en partición
CREATE INDEX ON events_2026_04(tenant_id, event_type);

-- Purga de datos viejos: ultra-rápido
ALTER TABLE events DETACH PARTITION events_2024_01;
DROP TABLE events_2024_01;