服务于区块链开拓者

www.zhidnet.com

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、快速删除重复的记录的方法:

  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 ) 

    相关子查询在处理大数据量的情况下尽量避免使用。

    

    

    

      

  

  

 

 

  

posted on 2014-07-27 17:44  知点网  阅读(4672)  评论(0编辑  收藏  举报