1

我正面临从名为 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;
4

2 回答 2

4

我会先在一个 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;

不要忘记重新申请所有权限。

于 2012-12-04T08:43:13.797 回答
0

您应该links_data(id_folder)在 table 的外键列上和外键列上都有一个索引link_folders

但是如果要清理的数据量很大(例如超过 30%)并且删除不是一个连续的过程,您最好进行维护 -> 重新创建包含所需数据的表。插入比删除快 n 倍。

于 2012-12-04T08:37:57.683 回答