【oracle】清理重复还是把不重复的数据放入临时表,清空原表后再塞回较合理

让我们先建一个实验表:

create table dup(
id int,
name nvarchar2(5),
age int,
primary key(id));

然后塞入一百万数据:

insert into dup 
select rownum,
       dbms_random.string('*',dbms_random.value(1,5)),
       dbms_random.value(18,81)
    from dual
    connect by level<1000001;

看看name不算重复的话有多少:

SQL> select count(*) from (select min(id) from dup group by name);

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.45

只有三十三万个,有六十七万条记录需要删除。

如果我们直接执行如下的删除,只怕会要等到猴年马月,反正我是剪完脚趾甲它还没执行完,大家有等到结果的请在留言里说明时长。

delete from dup where id not in (select min(id) from dup group by name)

所以这个方案是行不通的,删除表是CRUD里最消耗资源的,大批量删除是不推荐的,最好是找出需要的、清空原表、再塞回去。

下面就来建新表:

SQL> create table dup2 as select * from dup where id in (select min(id) from dup group by name);

表已创建。

已用时间:  00: 00: 01.15

然后清空原表:

SQL> truncate table dup;

表被截断。

已用时间:  00: 00: 00.08

再塞回去:

SQL> insert into dup select * from dup2;

已创建335572行。

已用时间:  00: 00: 00.68

以上三项加起来不到两秒,和直接delete的方案简直有天壤之别。

再看看是否还有重复项:

SQL> select count(*) from dup;

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.01
SQL> select count(*) from (select min(id) from dup group by name);

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.22
SQL> select count(*) from (select distinct name from dup);

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.16

三项都是一样的,自然没有重复了。

最后的结论就是 选不重复的进临时表,清空后再塞回比直接删要快且省事。

下面是实验用到的全部SQL:

SQL> insert into dup
  2  select rownum,
  3         dbms_random.string('*',dbms_random.value(1,5)),
  4         dbms_random.value(18,81)
  5      from dual
  6      connect by level<1000001;

已创建1000000行。

SQL> set timing on;
SQL> select count(*) from (select min(id) from dup group by name);

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.45
SQL> create table dup2 as select * from dup where id in (select min(id) from dup group by name);

表已创建。

已用时间:  00: 00: 01.15
SQL> truncate table dup;

表被截断。

已用时间:  00: 00: 00.08
SQL> insert into dup select * from dup2;

已创建335572行。

已用时间:  00: 00: 00.68
SQL> commit;

提交完成。

已用时间:  00: 00: 00.01
SQL> select count(*) from dup;

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.01
SQL> select count(*) from (select min(id) from dup group by name);

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.22
SQL> select count(*) from (select distinct name from dup);

  COUNT(*)
----------
    335572

已用时间:  00: 00: 00.16
SQL>

-END-

原文地址:https://www.cnblogs.com/heyang78/p/15291032.html