ORACLE 10G删除使用FORALL

时间:2012-10-03 01:46:51

标签: performance oracle bulk-load

我有一个txn表,每月有200万行我使用存储过程将数据加载到该表中。如果在我的过程中失败并且我曾经再次加载,我需要使用以下内容删除事务。

Table TXN structure

TXN_ID    NUMBER primary key 
TXN_AMT   number
YEAR    varchar2
MONTH   varchar2

我可以在这里使用批量收集,但是在我需要的where子句中

DELETE FROM TXN WHERE YEAR=cYear and Month=cMonth 

请告知我如何快速实现

2 个答案:

答案 0 :(得分:1)

  

“如果失败,我需要使用以下内容删除交易   在我的过程中,我曾经再次加载。“

看来你的实际问题是加载过程。您应该将整个负载定义为一个工作单元,即在2000000行的末尾进行单次提交。然后,您不必在发生故障时删除任何内容。

目前你显然有间歇性的提交。可能有几个原因导致您认为需要这样做,但它们都是假的。您只需要让DBA调整UNDO表空间的大小,使其大小适合您的数据量。或者,您需要重新编写加载过程,以便识别已加载(即已提交)的行;如果发生故障,您可以加载剩余部分。


就加快删除过程而言,您没有太多选择。 FORALL处理速度不会更快:PL / SQL会产生开销,因此不会比直接DELETE便宜。除非你有一张十年的数据表,否则(YEAR,MONTH)的索引不会有任何用处。

如果你有Enterprise Edition和许多CPU,你可以尝试使用PARALLEL DML在更短的时间内执行删除。

但是,与任何调优问题一样,您需要了解语句的当前执行路径,这意味着从解释计划开始。你知道,它们不仅仅适用于SELECT。

答案 1 :(得分:0)

作为替代方法,因为您要删除数据基础月和年

  • 您可以在表格中创建月分区,并在不需要时删除特定月份的分区。 (ALTER TABLE TABLENAME DROP PARTITION PARTION_NAME)
  • 同样,如果加载失败,只需截断该月份分区并再次加载。
  • 您可以进一步编写PL / SQL作业,该作业可以将分区基础保留为预定义条件,假设2012年12月1日为DROP PARTION_DEC_2011。 并在您使用它加载新数据前2个月添加一个分区。