【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-

 

posted @   逆火狂飙  阅读(131)  评论(1编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2017-09-15 【高中数学/对数】a=log(11,13) vs b=log(41,47)
2017-09-15 【高中数学/对数/导数】比较两数a=log_5_7和b=log_7_10的大小
2017-09-15 【高中数学/对数/比大小】a=log_5_3 vs b=log_8_5
2017-09-15 【高中数学/对数/比大小】a=log_5_7 vs b=log_11_14
2017-09-15 【Canvas与诗词】铁马冰河入梦来
2013-09-15 JS计算本周一和本周五的日期
2013-09-15 【java/image】采用直接操作像素的办法对png图片进行反色处理
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示