删除Oracle中非常大的记录集的最佳方法

前端之家收集整理的这篇文章主要介绍了删除Oracle中非常大的记录集的最佳方法前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我管理的应用程序具有非常大的(几乎1TB的数据,在一个表中有超过5亿行)Oracle数据库后端.数据库并没有真正做任何事情(没有SProcs,没有触发器或任何东西)它只是一个数据存储.

每个月我们都需要从两个主表中清除记录.清除的标准各不相同,是行年龄和几个状态字段的组合.我们通常最终每月清除1000到5000万行(我们通过导入每周增加约3-5万行).

目前我们必须批量删除大约50,000行(即删除50000,comit,删除50000,提交,重复).尝试一次删除整个批处理会使数据库在大约一小时内无响应(取决于行数).像这样批量删除行是非常粗糙的系统,我们通常必须“在时间允许的情况下”在一周内完成;允许脚本连续运行会导致用户无法接受的性能下降.

我相信这种批量删除也会降低索引性能并产生其他影响,最终导致数据库性能下降.一个表上有34个索引,索引数据大小实际上大于数据本身.

以下是我们的一位IT人员用来执行此清除的脚本:

  1. BEGIN
  2. LOOP
  3.  
  4. delete FROM tbl_raw
  5. where dist_event_date < to_date('[date]','mm/dd/yyyy') and rownum < 50000;
  6.  
  7. exit when sql%rowcount < 49999;
  8.  
  9. commit;
  10.  
  11. END LOOP;
  12.  
  13. commit;
  14.  
  15. END;@H_301_10@
  16. 这个数据库必须达到99.99999%,我们每年只有一个2天的维护时间.

  17. 我正在寻找一种更好的方法删除这些记录,但我还没有找到任何记录.有什么建议?

带有“A”和“B”的逻辑可能会隐藏在可以进行分区的虚拟列后面:
  1. alter session set nls_date_format = 'yyyy-mm-dd';
  2. drop table tq84_partitioned_table;
  3.  
  4. create table tq84_partitioned_table (
  5. status varchar2(1) not null check (status in ('A','B')),date_a date not null,date_b date not null,date_too_old date as
  6. ( case status
  7. when 'A' then add_months(date_a,-7*12)
  8. when 'B' then date_b
  9. end
  10. ) virtual,data varchar2(100)
  11. )
  12. partition by range (date_too_old)
  13. (
  14. partition p_before_2000_10 values less than (date '2000-10-01'),partition p_before_2000_11 values less than (date '2000-11-01'),partition p_before_2000_12 values less than (date '2000-12-01'),--
  15. partition p_before_2001_01 values less than (date '2001-01-01'),partition p_before_2001_02 values less than (date '2001-02-01'),partition p_before_2001_03 values less than (date '2001-03-01'),partition p_before_2001_04 values less than (date '2001-04-01'),partition p_before_2001_05 values less than (date '2001-05-01'),partition p_before_2001_06 values less than (date '2001-06-01'),-- and so on and so forth..
  16. partition p_ values less than (maxvalue)
  17. );
  18.  
  19. insert into tq84_partitioned_table (status,date_a,date_b,data) values
  20. ('B',date '2008-04-14',date '2000-05-17','B and 2000-05-17 is older than 10 yrs,must be deleted');
  21.  
  22.  
  23. insert into tq84_partitioned_table (status,date '1999-09-19',date '2004-02-12','B and 2004-02-12 is younger than 10 yrs,must be kept');
  24.  
  25.  
  26. insert into tq84_partitioned_table (status,data) values
  27. ('A',date '2000-06-16',date '2010-01-01','A and 2000-06-16 is older than 3 yrs,date '2009-06-09',date '1999-08-28','A and 2009-06-09 is younger than 3 yrs,must be kept');
  28.  
  29. select * from tq84_partitioned_table order by date_too_old;
  30.  
  31. -- drop partitions older than 10 or 3 years,respectively:
  32.  
  33. alter table tq84_partitioned_table drop partition p_before_2000_10;
  34. alter table tq84_partitioned_table drop partition p_before_2000_11;
  35. alter table tq84_partitioned_table drop partition p2000_12;
  36.  
  37. select * from tq84_partitioned_table order by date_too_old;@H_301_10@

猜你在找的Oracle相关文章