日期:2014-05-16  浏览次数:20325 次

两种查询和删除重复记录的方法及其性能比较
这里我来给出两种查询和删除重复记录的方法,一种是使用rowid辅助完成的,另外一种是借助分析函数的力量来完成的。
这两种方法的执行效率相对其他方法是高效的。即便如此,这两种方法之间也有着本质上的性能区别,我将通过实验的方式给大家展示一下这两种方法,并道出其中的本质差别。

1.创建实验用表并初始化几条样本数据
sec@ora10g> create table t (x number, y varchar2(10));
sec@ora10g> insert into t values (1, 'sec');
sec@ora10g> insert into t values (2, 'Andy01');
sec@ora10g> insert into t values (2, 'Andy02');
sec@ora10g> insert into t values (3, 'Anna');
sec@ora10g> insert into t values (4, 'Anna');
sec@ora10g> insert into t values (5, 'John');
sec@ora10g> commit;
sec@secooler> analyze table t compute statistics for table for all indexes for all indexed columns;

Table analyzed.

sec@ora10g> select * from t;

         X Y
---------- --------------------
         1 sec
         2 Andy01
         2 Andy02
         3 Anna
         4 Anna
         5 John

6 rows selected.

2.第一种使用rowid辅助查询和删除重复记录的方法
1)查询重复记录
sec@ora10g> SELECT *
  2    FROM t t1
  3   WHERE t1.ROWID <> (SELECT MIN (t2.ROWID)
  4                        FROM t t2
  5                       WHERE t1.x = t2.x)
  6  /

         X Y
---------- --------------------
         2 Andy02

BTW:如果想要查询x和y字段同时重复的内容,可以在上面的子查询中再添加一个“AND t1.y = t2.y”条件即可。

2)删除重复记录
可以简单的将上面的查询语句改写成删除语句便可完成删除任务。
sec@ora10g> DELETE FROM t t1
  2        WHERE t1.ROWID <> (SELECT MIN (t2.ROWID)
  3                             FROM t t2
  4                            WHERE t1.x = t2.x)
  5  /

1 row deleted.

可以看到,此时x字段重复的内容已经被删除了。
sec@ora10g> select * from t;

         X Y
---------- --------------------
         1 sec
         2 Andy01
         3 Anna
         4 Anna
         5 John

3.第二种使用分析函数辅助查询和删除重复记录的方法
1)使用分析函数可以快速的定位重复记录的位置,下面结果中rn值大于1的行即表示重复行。
sec@ora10g> SELECT t1.x,
  2         t1.y,
  3         ROW_NUMBER () OVER (PARTITION BY t1.x ORDER BY t1.ROWID) rn
  4    FROM t t1
  5  /

         X Y                            RN
---------- -------------------- ----------
         1 sec