Bevor meine Fragen beantwortet werden, würde ich folgendermaßen vorgehen:
Minimieren Sie die Anzahl der Erklärungen und die Arbeit, die sie relativ machen.
Alle Szenarien gehen davon aus, dass Sie eine ID-Tabelle haben (PURGE_IDS
) zum Löschen aus TABLE_1
, TABLE_2
usw.
Erwägen Sie die Verwendung von CREATE TABLE AS SELECT für wirklich große Löschungen
Wenn es keine gleichzeitige Aktivität gibt und Sie mehr als 30 % der Zeilen in einer oder mehreren Tabellen löschen, löschen Sie nicht; Führen Sie ein create table as select
durch mit den Zeilen, die Sie behalten möchten, und tauschen Sie die neue Tabelle gegen die alte Tabelle aus. INSERT /*+ APPEND */ ... NOLOGGING
ist überraschend billig, wenn Sie es sich leisten können. Selbst wenn Sie einige gleichzeitige Aktivitäten haben, können Sie möglicherweise die Online-Tabellenneudefinition verwenden, um die Tabelle direkt neu zu erstellen.
Führen Sie keine DELETE-Anweisungen aus, von denen Sie wissen, dass sie keine Zeilen löschen
Wenn ein ID-Wert in höchstens einer der sechs Tabellen vorhanden ist, verfolgen Sie, welche IDs Sie gelöscht haben – und versuchen Sie nicht, diese IDs aus einer der anderen Tabellen zu löschen.
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;
und wiederholen.
Verwalten Sie Parallelität, wenn Sie müssen
Eine andere Möglichkeit besteht darin, eine PL/SQL-Schleife über die Tabellen zu verwenden und eine auf die Anzahl der Zeilen beschränkte Löschanweisung auszugeben. Dies ist höchstwahrscheinlich angemessen, wenn es eine erhebliche gleichzeitige Einfüge-/Aktualisierungs-/Löschlast für die Tabellen gibt, für die Sie die Löschvorgänge ausführen.
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;