Gestisco un'applicazione che ha un back-end di database Oracle molto grande (quasi 1 TB di dati con oltre 500 milioni di righe in una tabella). Il database non fa davvero nulla (niente SProcs, niente trigger o altro) è solo un archivio dati.
Ogni mese ci viene richiesto di eliminare i record dalle due tabelle principali. I criteri per l'eliminazione variano ed è una combinazione di età delle righe e un paio di campi di stato. In genere finiamo per eliminare tra 10 e 50 milioni di righe al mese (aggiungiamo circa 3-5 milioni di righe alla settimana tramite le importazioni).
Attualmente è necessario eseguire questa eliminazione in batch di circa 50.000 righe (ovvero eliminare 50000, comit, eliminare 50000, commit, ripetere). Il tentativo di eliminare l'intero batch in una sola volta rende il database non rispondente per circa un'ora (a seconda del numero di righe). L'eliminazione delle righe in lotti come questo è molto approssimativa sul sistema e in genere dobbiamo farlo "come il tempo lo permette" nel corso di una settimana; consentire l'esecuzione continua dello script può comportare un peggioramento delle prestazioni inaccettabile per l'utente.
Ritengo che questo tipo di eliminazione in batch comprometta anche le prestazioni dell'indice e abbia altri impatti che alla fine possono compromettere le prestazioni del database. Esistono 34 indici su una sola tabella e la dimensione dei dati dell'indice è in realtà maggiore dei dati stessi.
Ecco lo script utilizzato da una delle nostre persone IT per eseguire questa eliminazione:
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;
Questo database deve essere al 99.99999% e abbiamo una finestra di manutenzione di 2 giorni una volta all'anno.
Sto cercando un metodo migliore per rimuovere questi record, ma devo ancora trovarne uno. Eventuali suggerimenti?