Tablas particionadas en Oracle (I): range y list
Dividir una tabla gigante en trozos administrables es la técnica de tuning más rentable de Oracle: esta primera parte cubre el particionado por rangos y por listas.
Cuando una tabla supera unos cientos de millones de filas, los índices empiezan a sufrir y los DELETE masivos se vuelven inviables. El particionado ataca el problema por física: en lugar de una tabla enorme, el motor mantiene varias piezas más pequeñas, cada una con sus índices y su segmento de almacenamiento. Las consultas solo visitan las piezas necesarias (poda de particiones) y el mantenimiento —borrar un mes antiguo— es eliminar una pieza entera, operación de segundos. Oracle ofrece tres estrategias; esta primera entrega cubre las dos clásicas, range y list.
Particionado por rangos: el caballo de batalla
El caso canónico es la tabla temporal: ventas, eventos, logs. Se define una columna de partición —casi siempre una fecha— y límites superiores para cada trozo:
CREATE TABLE ventas (
id NUMBER,
fecha DATE NOT NULL,
region VARCHAR2(20),
importe NUMBER(10,2)
)
PARTITION BY RANGE (fecha) (
PARTITION p2025 VALUES LESS THAN (DATE '2026-01-01'),
PARTITION p2026 VALUES LESS THAN (DATE '2027-01-01'),
PARTITION pmax VALUES LESS THAN (MAXVALUE)
);Con esta definición, un filtro por fecha hace que el plan solo visite las particiones afectadas. Comprobación en vivo: EXPLAIN PLAN muestra la columna PSTART y PSTOP con las particiones usadas; si aparece 1..3, la poda no funcionó y el filtro no está escrito sobre la columna de partición.
Administrar particiones sin parar nada
ALTER TABLE ventas ADD PARTITION p2027
VALUES LESS THAN (DATE '2028-01-01'); -- nueva al final
ALTER TABLE ventas SPLIT PARTITION pmax
AT (DATE '2028-01-01')
INTO (PARTITION p2028, PARTITION pmax); -- partir la cola
ALTER TABLE ventas DROP PARTITION p2024; -- purga antigua: instantanea
ALTER TABLE ventas TRUNCATE PARTITION p2025; -- vaciar sin borrarAquí está el argumento económico del particionado: DROP PARTITION elimina millones de filas sin generar deshacer ni redo, frente a un DELETE que puede tardar horas y llenar el tablespace de rollback. Un detalle importante: si existe un índice global, borrar la partición lo deja inutilizable salvo UPDATE INDEXES en la propia sentencia. Por eso los índices de tablas particionadas suelen ser locales: CREATE INDEX ix_v ON ventas (fecha) LOCAL;.
EXCHANGE: cargar millones de filas en un segundo
La operación favorita de quien hace ETL: EXCHANGE PARTITION intercambia el contenido de una partición por el de una tabla normal, un simple cambio de punteros en el diccionario:
-- cargar en tabla voladora, validar, intercambiar
CREATE TABLE ventas_stage NOLOGGING AS
SELECT * FROM ventas WHERE 1 = 0;
ALTER TABLE ventas
EXCHANGE PARTITION p202601 WITH TABLE ventas_stage
INCLUDING INDEXES WITHOUT VALIDATION;La carga masiva ocurre en la tabla stage, sin afectar a producción; el intercambio es metadatos puro. WITHOUT VALIDATION confía en que los datos respetan el rango —tú respondes de eso— y WITH VALIDATION lo comprueba a cambio de tiempo.
Particionado por listas: cuando la clave es una categoría
CREATE TABLE metricas (
pais VARCHAR2(2) NOT NULL,
fecha DATE,
valor NUMBER
)
PARTITION BY LIST (pais) (
PARTITION p_iberia VALUES ('ES', 'PT'),
PARTITION p_norte VALUES ('FR', 'DE', 'NL'),
PARTITION p_otros VALUES (DEFAULT)
);El particionado list reparte por valores discretos: países, regiones, tipos de documento. La partición DEFAULT actúa como red de seguridad para valores no previstos —sin ella, insertar un país nuevo lanza ORA-14400. Es habitual combinarlo: list por región en el primer nivel y range por fecha en el segundo (subparticionado), de modo que cada región tenga sus trozos mensuales.
Cuándo NO particionar
- Tablas pequeñas: el overhead de administración supera el beneficio, y la opción cuesta licencia (Enterprise, salvo que el cloud la haya incluido en tu plan).
- Consultas que nunca filtran por la columna de partición: no hay poda posible y solo se añade complejidad.
- Claves repartidas al azar: ahí manda el hash de la segunda parte.
La segunda entrega cubre hash e interval, incluida la partición automática mensual que jubiló los scripts nocturnos de ADD PARTITION. Para la purga de objetos y su relación con la papelera, sigue vigente el análisis del comando PURGE.