Trước khi các câu hỏi của tôi được trả lời, đây là cách tôi sẽ giải quyết vấn đề đó:
Giảm thiểu số lượng báo cáo và công việc chúng được phát hành trong điều kiện tương đối.
Tất cả các tình huống giả sử bạn có một bảng ID (PURGE_IDS
) để xóa khỏi TABLE_1
, TABLE_2
, v.v.
Cân nhắc sử dụng TẠO BẢNG NHƯ CHỌN cho những lần xóa thực sự lớn
Nếu không có hoạt động đồng thời và bạn đang xóa hơn 30% số hàng trong một hoặc nhiều bảng, đừng xóa; thực hiện create table as select
với các hàng bạn muốn giữ lại và hoán đổi bảng mới cho bảng cũ. INSERT /*+ APPEND */ ... NOLOGGING
rẻ bất ngờ nếu bạn có đủ khả năng. Ngay cả khi bạn có một số hoạt động đồng thời, bạn có thể sử dụng Định nghĩa lại bảng trực tuyến để xây dựng lại bảng tại chỗ.
Không chạy các câu lệnh DELETE mà bạn biết sẽ không xóa bất kỳ hàng nào
Nếu giá trị ID tồn tại ở nhiều nhất một trong sáu bảng, thì hãy theo dõi những ID nào bạn đã xóa - và đừng cố xóa những ID đó khỏi bất kỳ bảng nào khác.
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;
và lặp lại.
Quản lý tiền tệ đồng thời nếu bạn phải
Một cách khác là sử dụng PL / SQL lặp qua các bảng, đưa ra câu lệnh xóa giới hạn số hàng. Điều này rất có thể phù hợp nếu có tải trọng đồng thời chèn / cập nhật / xóa đáng kể đối với các bảng mà bạn đang chạy xóa.
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;