Zarządzam aplikacją, która ma bardzo duży (prawie 1 TB danych z ponad 500 milionami wierszy w jednej tabeli) zaplecze bazy danych Oracle. Baza danych tak naprawdę nic nie robi (bez SProc, żadnych wyzwalaczy itp.), To tylko magazyn danych.
Co miesiąc jesteśmy zobowiązani do usuwania danych z dwóch głównych tabel. Kryteria oczyszczania są różne i stanowią kombinację wieku wiersza i kilku pól statusu. Zwykle oczyszczamy od 10 do 50 milionów wierszy miesięcznie (dodajemy około 3-5 milionów wierszy tygodniowo poprzez import).
Obecnie musimy to usunąć w partiach po około 50 000 wierszy (tj. Usuń 50000, zatwierdzaj, usuwaj 50000, zatwierdzaj, powtarzaj). Próba usunięcia całej partii naraz powoduje, że baza danych nie odpowiada przez około godzinę (w zależności od liczby wierszy). Usuwanie wierszy w takich partiach jest bardzo trudne dla systemu i zwykle musimy to robić „jak pozwala na to czas” w ciągu tygodnia; zezwolenie na ciągłe działanie skryptu może spowodować obniżenie wydajności, które jest nie do przyjęcia dla użytkownika.
Uważam, że tego rodzaju usuwanie wsadowe zmniejsza również wydajność indeksu i ma inne skutki, które ostatecznie powodują pogorszenie wydajności bazy danych. W jednej tabeli znajdują się 34 indeksy, a rozmiar danych indeksu jest w rzeczywistości większy niż same dane.
Oto skrypt, z którego korzysta jeden z naszych informatyków, aby wykonać tę czystkę:
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;
Ta baza danych musi mieć wzrost o 99,99999%, a my mamy 2-dniowy okres konserwacji raz w roku.
Szukam lepszej metody usuwania tych rekordów, ale jeszcze jej nie znalazłem. Jakieś sugestie?