sábado, 8 de febrero de 2020

Borrado Masivo de datos en Oracle usando particiones

Borrado Masivo de datos en Oracle usando particiones

Borrar datos masívamente usando un comando delete afecta los recursos de la base de datos.
Si los borrados masivos son frecuentes en tu sistema, es mejor que organices tus tablas para que puedan soportar este comportamiento.

Puedes investigar mas sobre particiones en Oracle y las diferentes particiones que se pueden aplicar, en esta ocasión recomiendo las particiones por lista horizontales.

Ejemplo:
las particiones son para manejar grandes volúmenes de datos, pero para explicar mejor presento una tabla con pocos datos. 

Tabla tblRevisiones:

Revisioncodigodato1dato2
rev1sku1aaaaa12343
rev1sku2bbbb125324
rev1sku3ccc238305
rev1sku4dd351286
rev1sku5ff464267
rev1sku6ggg577248
rev1sku7hhhh690229
rev1sku8dd803210
rev1sku9ff916191
rev1sku10ggg1029172
rev1sku11hhhh1142153
rev1sku12dd1255134
rev1sku13ff1368115
rev2skucode1rojo12
rev2skucode2blanco15
rev2skucode3azul78
rev2skucode4rojo101
rev2skucode5blanco134
rev2skucode6azul167
rev2skucode7rojo200
rev2skucode8blanco233
rev3sku1datosvalores
rev3sku2datosvalores
rev3sku3datosvalora
rev3sku4datosvalores

Tenemos una tabla que nos interesa borrar todos los datos que pertenecen a una dicha revisión es decir, la rev1, rev2, rev3 o cualquier otra revisión que pudiera existir.

Lo que hacemos en este caso es preparar la tabla para que almacene todos los registros rev1 en una partición, todos los rev2 en otra partición, todos los rev3 en otra partición y que pueda crear automáticamente otras particiones cuando se ingresen nuevas revisiones:

Paritción rev1

Revisioncodigodato1dato2
rev1sku1aaaaa12343
rev1sku2bbbb125324
rev1sku3ccc238305
rev1sku4dd351286
rev1sku5ff464267
rev1sku6ggg577248
rev1sku7hhhh690229
rev1sku8dd803210
rev1sku9ff916191
rev1sku10ggg1029172
rev1sku11hhhh1142153
rev1sku12dd1255134
rev1sku13ff1368115

Partición rev2:

Revisioncodigodato1dato2
rev2skucode1rojo12
rev2skucode2blanco15
rev2skucode3azul78
rev2skucode4rojo101
rev2skucode5blanco134
rev2skucode6azul167
rev2skucode7rojo200
rev2skucode8blanco233

Particion rev3:
Revisioncodigodato1dato2
rev3sku1datosvalores
rev3sku2datosvalores
rev3sku3datosvalora
rev3sku4datosvalores


De esta manera, cuando necesitemos borrar todos los registros que pertencen a la rev1 por ejemplo será suficiente con el comando:

ALTER TABLE table_name TRUNCATE PARTITION partition_name

ALTER TABLE tblRevisiones TRUNCATE PARTITION rev1

Esto eliminará todos los registros que pertenecen a rev1 de manera inmediata, utilizando muy pocos recursos de la base de datos.

Crear Tabla Particionada

CREATE TABLE tblRevisiones (
    revision    VARCHAR2(30),
    codigo      VARCHAR2(30),
    dato1       VARCHAR2(30),
    dato2       NUMBER
)
PARTITION BY LIST (revision)
(
PARTITION rev1 VALUES ('rev1'),
PARTITION rev2 VALUES ('rev2'),
PARTITION rev3 VALUES ('rev3'),
PARTITION ERR VALUES (null)
);


De esta manera cuando se inserten registros, automáticamente se insertarán en la partición correspondiente según el valor de la revisión que contenga cada registro.

Crear Particiones de manera dinámica

Seguramente deseas crear particiones de forma dinámica , esto se puede hacer en un procedimiento almacenado:

vs_tabla := 'tblRevisiones';
vs_Particion := 'rev1';
vn_existe_particion := 0;

SELECT count(1
INTO vn_existe_particion 
FROM ALL_TAB_PARTITIONS 
WHERE TABLE_NAME = vs_table 
AND PARTITION_NAME = vs_Particion;

IF vn_existe_particion = 0 THEN
    EXECUTE IMMEDIATE 'ALTER TABLE tblRevisiones ADD PARTITION '
||vs_Partition
||' VALUES('''||vs_Partition||''')';
--ELSE
--    EXECUTE IMMEDIATE 'ALTER TABLE tblRevisiones TRUNCATE PARTITION ' 
-- || vs_Particion
END IF;
/* CONTINUAR CON EL PROCEDIMIENTO DE INSERTAR */

El ELSE que está comentado serviría para truncar la partición antes de insertar, pero si no se necesita entonces se hará la inserción normal, agregando registros a la partición correspondiente

El truncado solo se puede hacer si la partición existe, por eso va dentro de un ELSE.


Saludos a Yadir Rivera y Norman Hernández, espero les sea de utilidad