Zanim odpowiem na moje pytania, podejmę to w ten sposób:
Zminimalizuj liczbę oświadczeń i pracę, którą wykonują w ujęciu względnym.
Wszystkie scenariusze zakładają, że masz tabelę identyfikatorów (PURGE_IDS
), aby usunąć z TABLE_1
, TABLE_2
itp.
Rozważ użycie opcji CREATE TABLE AS SELECT w przypadku naprawdę dużych usunięć
Jeśli nie ma jednoczesnej aktywności i usuwasz ponad 30% wierszy w jednej lub kilku tabelach, nie usuwaj; wykonaj create table as select
z wierszami, które chcesz zachować, i zamień nową tabelę na starą. INSERT /*+ APPEND */ ... NOLOGGING
jest zaskakująco tani, jeśli możesz sobie na to pozwolić. Nawet jeśli masz jakieś równoległe działania, możesz użyć redefinicji tabeli online, aby odbudować tabelę na miejscu.
Nie uruchamiaj instrukcji DELETE, o których wiesz, że nie usuną żadnych wierszy
Jeśli wartość identyfikatora istnieje co najwyżej w jednej z sześciu tabel, śledź, które identyfikatory zostały usunięte – i nie próbuj usuwać tych identyfikatorów z żadnej z pozostałych tabel.
CREATE TABLE TABLE1_PURGE NOLOGGING
AS
SELECT ID FROM PURGE_IDS INNER JOIN TABLE_1 ON PURGE_IDS.ID = TABLE_1.ID;
DELETE FROM TABLE1 WHERE ID IN (SELECT ID FROM TABLE1_PURGE);
DELETE FROM PURGE_IDS WHERE ID IN (SELECT ID FROM TABLE1_PURGE);
DROP TABLE TABLE1_PURGE;
i powtórz.
Zarządzaj współbieżnością, jeśli musisz
Innym sposobem jest użycie pętli PL/SQL nad tabelami, wydając instrukcję usuwania z ograniczeniem do liczby wierszy. Jest to najprawdopodobniej odpowiednie, jeśli występuje znaczne jednoczesne wstawianie/aktualizowanie/usuwanie w tabelach, dla których wykonujesz operacje usuwania.
declare
l_sql varchar2(4000);
begin
for i in (select table_name from all_tables
where table_name in ('TABLE_1', 'TABLE_2', ...)
order by table_name);
loop
l_sql := 'delete from ' || i.table_name ||
' where id in (select id from purge_ids) ' ||
' and rownum <= 1000000';
loop
commit;
execute immediate l_sql;
exit when sql%rowcount <> 1000000; -- if we delete less than 1,000,000
end loop; -- no more rows need to be deleted!
end loop;
commit;
end;