Oracle 利用rowid快速删除大表中部分数据

问题:

  我们在负责数据仓库的时候,都会有一个中间表(ODS层)来存放部分粒度很细的数据,虽然中间表不是归档表,但是由于每日的业务数据量庞大,每个中间表也会存放有几千万条数据,业务时间跨度达到一个月。而且业务数据提交的是不会停止的,因此,我们在对中间表进行数据更新的时候都会先删除再插入数据,那么问题来了:如何才能快速的删除大表的部分数据。

方案:

  利用Oracle自带的伪列ROWID进行匹配删除,先将满足条件的ROWID获取回来,然后利用ROWID批量删除代替单条语句删除部分数据。

环境:

  • MID_BASE_OUTPATIENT_TEST 是分区表,分区键为业务时间,每个月一个分区,每个分区根据事件号(最小粒度,主键)进行HASH分区,在该列上建立本地分区索引。
  • MID_BASE_OUTPATEINT_INFO是每天的变化数据。

实现脚本:

--根据rowid批量删除
declare
  cursor v_cur is
    select rowid
      from mid_base_outpatient_test mid
     where exists (select 1
              from mid_base_outpatient_info t
             where t.event = mid.event)
     order by rowid;   --获取目标表上要删除行的rowid

  type v_rowid_type is table of rowid index by pls_integer;
  v_rowid v_rowid_type;

begin

  open v_cur;

  while (true) loop
    fetch v_cur bulk collect
      into v_rowid limit 1000;
    forall i in v_rowid.first .. v_rowid.last
      delete from mid_base_outpatient_test where rowid = v_rowid(i);--批量删除数据
    commit;
    exit when v_cur%NOTFOUND;
  end loop;

  close v_cur;

end;

  以上这种方式比直接删除数据:

delete from mid_base_outpatient_test mid
 where exists
 (select 1 from mid_base_outpatient_info t where t.event = mid.event)

  快了一倍的时间

你可能感兴趣的:(数据库)