Oracle快速删除表中重复数据——适用百万级数据

来源:互联网 发布:基金数据库 编辑:程序博客网 时间:2024/05/29 17:48

本文是针对部分字段重复的表,对于表中完全重复的数据可以使用distinct。

Oracle删除表中重复数据有多种方法,

网上较多的一种如下:

delete from gljyjl jl where (jl.djbbh,jl.bgsbh) in (select djbbh,bgsbh from gljyjl group by djbbh,bgsbh having count(*) > 1) and rowid not in (select min(rowid) from gljyjl group by djbbh,bgsbh having count(*)>1);

但此方法执行效率太低,表中有40多万条数据,重复数据有三万多。此方法执行了几个小时,还没结束。。。

通过查看该语句的执行计划,发现竟需要执行46个多小时!!!



无奈只能放弃此方法!


最终想到一种解决方案:可以先删除表中重复的一部分数据,也就是说分多次删除重复数据。


delete from gljyjl where rowid in (select min(rowid) from gljyjl group by djbbh,bgsbh having count(*) > 1);

该SQL语句很简单,通过djbbh,bgsbh两个字段进行分组,选取出这两个字段重复的记录,

获得每个分组中rowid最小的那条记录的rowid,然后把这条记录删除。

这样便可以把每组中重复的记录都删掉一条。

之后重复执行该条SQL语句,直到所有的重复记录全部删除完就可以了。



但如果每组中重复的数据有上千条,就需要重复执行该SQL语句上千次。

这样便会操作上千次了,不是太方便!

解决办法是编写存储过程,重复执行该SQL语句,直到受影响的SQL为0。

create or replace procedure deleteEqualsasbegin   loop    delete from gljyjl where rowid in (select min(rowid) from gljyjl group by djbbh,bgsbh having count(*) > 1);    dbms_output.put_line('删除了'||to_char(sql%rowcount)||'行');    exit when sql%rowcount = 0;  end loop;end;/



执行该存储过程!


exec deleteEquals();


该表中的重复数据便会全部删除!



1 0