在Oracle中删除数百万行的最佳方法

时间:2018-09-11 05:50:02

标签: sql oracle plsql

我有一个表,该表具有1万亿行和8个索引,2个外键,并按保存年份的列进行分区。我为每个人计算的年份(单独包装),应删除少于该年份的数据。当前最后一个分区有6.51亿行,我需要从该分区中删除约600万行。以下是我尝试过的事情

  1. 删除香草-花费了很多时间

  2. 批量批量删除-花费了大量时间

  3. 交换分区-这是最快的,但是所有8个索引都变为不可用状态,我需要重建所有索引,这又需要时间。当前,Exchange分区也不起作用,因为父表具有隐藏的列,并且分区抛出错误

      

    ORA-12996:无法删除系统生成的虚拟列

此表有30万人,我计算了每个人的年份,现在遍历每个人并将其删除,但在删除每个人后才提交。

2 个答案:

答案 0 :(得分:3)

您可以尝试:

  1. 创建一个新的未分区表
  2. 在其上创建索引
  3. 使用直接路径(APPEND)nologging插入来添加要保留的行。
  4. 进行分区交换
  5. 截断非分区表
  6. 从(3)重复其他分区
  7. 删除未分区的表
  8. 进行备份

请注意,索引是在插入过程中生成的,方法是将所需数据记录到临时段中,然后再扫描这些临时段以构建索引,而不是完全扫描表本身。

答案 1 :(得分:-1)

您可以执行以下操作:

create table tablewithrelevantdata unrecoverable as select * from tabletobedeleted where ....;
drop table tabletobedeleted;
rename tablewithrelevantdata to tabletobedeleted;
create index tabletobedeleted_idx1 on tabletobedeleted(c1,c2) unrecoverable parallel 5;

由于您有索引,因此我将再次检查复合表(如此类表)上是否有索引

  1. 学生
  2. 老师
  3. 班级

这里Class以学生和老师的ID为主要关键字。在StudentId的{​​{1}}和Teacherid上建立索引很重要。

此外,您可以使用delete,例如:

Class