[英]Oracle delete query taking long time to delete the records from the table
[英]Delete records from Oracle in sets
我正面臨着從名為links_data的表中刪除記錄集的問題,因為要刪除大量數據並且Oracle DB耗盡了臨時空間。
對於我對存儲過程知之甚少,我編寫了下面的代碼。 但是存儲過程看起來也很慢。
方案是我需要從links_data表中刪除行,其中links_data表中的nm_folder列與link_folders表具有外鍵關系。 link_folders表中的nm_folder是主鍵,我打算一次刪除10000條記錄並提交,然后再次刪除10000條記錄並提交。
請有人幫我優化這個查詢。 感謝和問候,
Declare
Type ty_link_floder is table of number;
tble_id_folder ty_link_floder;
Cursor c_data is
select id_folder from link_folders where nm_folder='User Hotlist';
Begin
OPEN c_data;
LOOP
FETCH c_data
BULK COLLECT INTO tble_id_folder LIMIT 10000;
EXIT WHEN tble_id_folder.count = 0;
FORALL i IN tble_id_folder.first .. tble_id_folder.last
DELETE FROM links_data
WHERE id_folder = tble_id_folder(i);
COMMIT;
-- Process contents of collection here.
DBMS_OUTPUT.put_line(tble_id_folder.count || ' rows deleted from links_data table so far');
tble_id_folder.delete;
END LOOP;
CLOSE c_data;
Exception
When others Then
Commit;
Raise;
End;
我先在一個SQL語句中嘗試它:
DELETE FROM links_data d
WHERE id_folder IN (
SELECT id_folder FROM links_folder WHERE nm_folder='User Hotlist');
如果用盡臨時空間並且DBA無法設置額外的臨時空間,最好的方法是重新創建沒有應刪除的行的表:
CREATE TABLE links_data_tmp AS
SELECT * FROM links_data d
WHERE id_folder NOT IN (
SELECT id_folder FROM links_folder WHERE nm_folder='User Hotlist');
在此之后,你需要重建所有的索引和約束links_data_tmp
已定義links_data
。 然后你可以將臨時表與真實表交換:
RENAME links_data TO links_data_old;
RENAME links_data_tmp TO links_data;
別忘了重新申請所有特權。
您應該在links_data(id_folder)
以及表link_folders
上的外鍵列上有link_folders
。
但是,如果要清理的數據量非常大(例如超過30%)並且刪除不是連續過程,則最好進行維護 - >使用所需數據重新創建表。 插入比刪除快n倍。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.