当前位置: 代码迷 >> 综合 >> Oracle库Delete删除千万以上普通堆表数据的方法
  详细解决方案

Oracle库Delete删除千万以上普通堆表数据的方法

热度:97   发布时间:2024-02-06 02:27:45.0

需求:Oracle数据库delete删除普通堆表千万条历史记录。

直接删除的影响:

  • 可能由于undo表空间不足从而导致最终删除失败的问题
  • 可能导致undo表空间过度使用,影响到其他用户正常操作

改进方案:每删除1k行就提交一次。(这样就把一个大事物拆分成了若干个小事物)

下面方法以删除2014年之前的所有记录为例,请根据你的实际情况修改,防止误操作。

一、 方法1

-- [del_cursor] 游标名
-- [table_name] 你要删除数据的表名
-- [time_stamp] 你用作过滤条件的表的时间字段名称
declarecursor [del_cursor] is select a.*, a.rowid row_id from [table_name] a order by a.rowid;
beginfor v_cusor in [del_cursor] loopif v_cusor.[time_stamp] < to_date('2014-01-01','yyyy-mm-dd') thendelete from [table_name] where rowid = v_cusor.row_id;end if;if mod([del_cursor]%rowcount,1000)=0 thencommit;end if;end loop;commit;
end;
/

 

二、 方法2

-- [table_name] 你要删除数据的表名
-- [time_stamp] 你用作过滤条件的表的时间字段名称
declare  
maxrows number default 1000;
delete_ct number default 0;
begin
select count(1)/maxrows  into delete_ct from [table_name] where [time_stamp] < to_date('2014-01-01','yyyy-mm-dd');
for i in 1..TRUNC(delete_ct)+1
loop
delete [table_name] where [time_stamp] < to_date('2014-01-01','yyyy-mm-dd') and rownum <= maxrows;
commit;
end loop ;
end;
/

 

两种方法的核心的思路都是把一个大事务拆分成了若干个小事务,无论采用哪种方法,都建议先在对应的测试环境中测试后再考虑是否可以在实际生产使用。顺便说一句,这样的大表应该要综合考虑下是否可以改造成分区表。

  相关解决方案