Sebelum pertanyaan saya dijawab, beginilah cara saya melakukannya:
Minimalkan jumlah pernyataan dan pekerjaan yang mereka lakukan yang dikeluarkan secara relatif.
Semua skenario mengasumsikan Anda memiliki tabel ID (PURGE_IDS
) untuk menghapus dari TABLE_1
, TABLE_2
, dll.
Pertimbangkan Menggunakan CREATE TABLE AS SELECT untuk penghapusan yang sangat besar
Jika tidak ada aktivitas bersamaan, dan Anda menghapus 30+ % baris dalam satu atau beberapa tabel, jangan hapus; lakukan create table as select
dengan baris yang ingin Anda pertahankan, dan tukar tabel baru dengan tabel lama. INSERT /*+ APPEND */ ... NOLOGGING
sangat murah jika Anda mampu membelinya. Bahkan jika Anda memiliki beberapa aktivitas bersamaan, Anda mungkin dapat menggunakan Definisi Ulang Tabel Online untuk membangun kembali tabel di tempat.
Jangan jalankan pernyataan DELETE yang Anda tahu tidak akan menghapus baris apa pun
Jika nilai ID paling banyak ada di salah satu dari enam tabel, lacak ID mana yang telah Anda hapus - dan jangan coba menghapus ID tersebut dari tabel lainnya.
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;
dan ulangi.
Kelola Konkurensi jika Anda harus
Cara lain adalah dengan menggunakan perulangan PL/SQL di atas tabel, mengeluarkan pernyataan penghapusan baris-terbatas. Ini kemungkinan besar sesuai jika ada beban bersamaan yang signifikan menyisipkan/memperbarui/menghapus terhadap tabel tempat Anda menjalankan penghapusan.
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;