簡體   English   中英

從集合中刪除Oracle中的記錄

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM