一、快速删除重复的记录的方法:
1、通过创建临时表删除重复的的记录
1)创建emp表的临时表,把数据导入临时表中,删除原来的表中的数据然后把临时表中的数据导入原表
create table emp_tmp
as select distinct * from emp;
2)清空原表记录
truncate table emp
3)将临时表中的数据添加到原来的表
insert into emp select * from emp_tmp;
这种方法可以实现需求,但是对于一个千万条记录的表来说会很慢。在生产系统上会带来很大的系统开销,显然该方法不可行。
2、利用rowid结合max或者min函数
rowid是数据的详细地址,利用rowid可以帮助oracle快速定位某行数据的具体位置。rowid可以分为两种,普通表中 的rowid是物理rowid,索引组织表中 的rowid是逻辑 rowid。
使用rowid快速唯一确定重复行结合max或者min函数实现删除重复行
delete from emp e1 where e1.rowid not in ( select max(rowid) from emp e2 where e2.column1=e1.column1 and e2.column2=e1.column2,and e2.column3=e1.column3)
或者
delete from emp e1 where e1.rowid < ( select max(rowid) from emp e2 where e2.column1=e1.column1 and e2.column2=e1.column2,and e2.column3=e1.column3)
或者
delete from emp e1 where e1.rowid > ( select min(rowid) from emp e2 where e2.column1=e1.column1 and e2.column2=e1.column2,and e2.column3=e1.column3)
该方法是使用相关子查询确定最多或者最小rowid然后执行删除操作。如果是少量数据时可以使用该方法,但是如果是千万级的数据量最好不要使用相关子查询。这样的sql执行速度很慢,不适合于生产环境。
与以上思路相同使用group by子句可以减少明显的比较条件提高系统的效率
delete from emp where rowid not in (select max(rowid) from emp group by column1,column2,column3)
但是在千万级数据量的系统中使用in或者not in仍然会很大程度上降低系统的效率,最好不要使用。
二、根据指定的列删除包含重复列值的记录(这种情况一般很少见,因为根据rowid删除的话很难判断删除以后保留下的行的其他列的值到底是什么)
主要的应用场景:在对数据库中的表的一列或者几列试图创建唯一索引时系统提示ora-01452:不能创建唯一索引,发现重复记录
该情景一般讲指定的列就是表中的主键列
1)大数据量的情况下:
1、查找重复列值的记录
select empno from emp group by empno having count(*)>1
或者
select * from emp where rowid not in(select min(rowid) from emp group by empno )
2、删除重复记录(列上建有索引的时候使用时效率会更高)
delete from emp where empno in (select empno from emp group by empno having count(*)>1)
and rowid not in (select min(rowid) from emp group by empno having count(*)>1)
或者
delete from emp where rowid not in (select min(rowid) from emp group by empno)
这是执行效率最高的删除包含重复列值的记录的方法
2)适合于少量重复记录的情况(对于大量的重复记录以下语句的执行效率会很低)
1、查找重复列值的记录
select * from emp e1 where e1.rowid<>(select min(rowid) from emp e2 where e2.empno=e1.empno)
2、删除重复记录
delete from emp e1 where e1.rowid <>(select min(rowid) from emp e2 where e2.empno=e1.empno )
相关子查询在处理大数据量的情况下尽量避免使用。