Administro una aplicación que tiene un back-end de base de datos Oracle muy grande (casi 1 TB de datos con más de 500 millones de filas en una tabla). La base de datos realmente no hace nada (sin SProcs, sin desencadenantes ni nada) es solo un almacén de datos.
Todos los meses estamos obligados a purgar registros de las dos tablas principales. El criterio para la purga varía y es una combinación de antigüedad de fila y un par de campos de estado. Por lo general, terminamos purgando entre 10 y 50 millones de filas por mes (agregamos alrededor de 3-5 millones de filas por semana a través de importaciones).
Actualmente tenemos que hacer esta eliminación en lotes de aproximadamente 50,000 filas (es decir, eliminar 50000, comit, eliminar 50000, commit, repetir). Intentar eliminar todo el lote al mismo tiempo hace que la base de datos no responda durante aproximadamente una hora (dependiendo del número de filas). Eliminar las filas en lotes como este es muy difícil para el sistema y, por lo general, tenemos que hacerlo "según lo permita el tiempo" en el transcurso de una semana; permitir que la secuencia de comandos se ejecute continuamente puede provocar una degradación del rendimiento que es inaceptable para el usuario.
Creo que este tipo de eliminación por lotes también degrada el rendimiento del índice y tiene otros impactos que eventualmente hacen que el rendimiento de la base de datos se degrade. Hay 34 índices en una sola tabla, y el tamaño de los datos del índice es en realidad mayor que los datos en sí.
Aquí está el script que una de nuestras personas de TI usa para hacer esta purga:
BEGIN
LOOP
delete FROM tbl_raw
where dist_event_date < to_date('[date]','mm/dd/yyyy') and rownum < 50000;
exit when SQL%rowcount < 49999;
commit;
END LOOP;
commit;
END;
Esta base de datos debe estar al 99.99999% y solo tenemos una ventana de mantenimiento de 2 días una vez al año.
Estoy buscando un mejor método para eliminar estos registros, pero aún no he encontrado ninguno. ¿Alguna sugerencia?