zoukankan      html  css  js  c++  java
  • 【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-

  • 相关阅读:
    sys_refcursor vs ref cursor in oracle
    Oracle-cursor动态游标
    游标(cursor)--显式游标&隐式游标、游标四个属性、循环遍历
    PL/SQL IF CASE
    python字符串的encode和decode
    python中raw_input()与input()
    Emacs显示行号
    Python爬虫——抓取糗百段子
    Python代码一定要对齐
    Python标准库内置函数——hasattr
  • 原文地址:https://www.cnblogs.com/heyang78/p/15291032.html
Copyright © 2011-2022 走看看