如何从Oracle表中批量删除大量数据

dus*_*sk7 2 sql database oracle oracle10g

我正在使用Oracle 10g,想从“人员”表中删除大约500万条记录(总共有1500万条记录),而在“订单”表中没有任何引用(总共有500万条记录)

由于一次删除500万条记录会导致撤消日志问题,因此我决定批量删除10万条记录。我正在使用以下查询:

DELETE FROM Persons p
      WHERE     City = 'ABC'
            AND NOT EXISTS
                   (SELECT O_Id
                      FROM Orders o
                     WHERE p.P_Id = o.P_Id)
            AND ROWNUM <= 100000
Run Code Online (Sandbox Code Playgroud)

现在的问题是,执行该查询所需的时间长达100k条记录,而执行该查询所需的时间却只有500万条记录,因为仍然会进行全表扫描和两个表的联接。

有没有一种有效的方法可以重写此查询以加快执行速度?还是用更好的连接条件替换NOT EXISTS子句?还是使用更好的方法将记录限制为100k?

PS这只是一次操作,因此我不能使用任何DDL操作,但是pl / sql很好

Gor*_*off 5

如果您希望此查询运行得更快,请添加以下两个索引:

 create index idx_persons_city_pid on persons(city, p_id);
 create index idx_orders_pid on orders(p_id);
Run Code Online (Sandbox Code Playgroud)


Cyr*_*972 5

根据我的经验,删除许多行的最快方法是:

解决方案1(由Tom Kyte推荐)

`SET TRANSACTION USE ROLLBACK SEGMENT <your_seg>
 DELETE FROM <tab1> WHERE <cond>
 COMMIT`
Run Code Online (Sandbox Code Playgroud)

要么

解决方案2

`create table new_table unrecoverable as select * from old_table where ....;
drop table old_table;
rename new_table to old_table;
create index old_table_idx1 on old_table(c1,c2) unrecoverable parallel 5;
`
Run Code Online (Sandbox Code Playgroud)

我在不同的上下文中使用了第二种解决方案:删除大量行始终是最快的。

另一种选择是将要删除的数据放在一个分区中,然后删除该分区(每个分区都有自己的回滚段,可以使用并行性,...)。