Oracle开发专题之:删除重复记录

2024-04-15 16:48

本文主要是介绍Oracle开发专题之:删除重复记录,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、测试环境:

假设目前我们有一个表:test,该表的结构如下:


效果如同前面两个方法一样,大量的连接、排序、分组让依靠rowid来删除重复记录变得很耗时,反而是采用方法1的情况下速度很快(本人测试了2次,都是连接测试服务器进行测试,第一次用时7.09秒,第二次用时14.656秒)。

小结:
在数据量不大的情况下,采用根据rowid或结合group by分组的方式是很快的,但是在海量数据的情况下则反而是方式一最快,因为省去了自连接、排序、分组的时间

 

SQL >   desc  test;
 Name                                      
Null ?    Type
 
-- --------------------------------------- -------- ----------------------------
 ID                                                   NUMBER
 SEQ                                                
NUMBER


现在我们向表中插入200W条数据,这200W条数据中有一半是重复的。

create   or   replace   procedure  gen_duplicated_records  as

  i 
number ;
  j 
number ;

begin
  
for  i  in   1  ..  2  loop
    
for  j  in   1  ..  1000000  loop
      
insert   into  test  values  (j, j  +   10 );
    
end  loop;
    
commit ;
  
end  loop;
end ;


我们的最终目的就是剔除这一半的重复记录。下面来看一下各种方法的使用及效率区别

二、使用临时表进行删除:

这个是最简单的思路了,创建一张临时表,将原表中的数据拷贝一半过去,再查询出来。

SQL >   set  timing  on ;
SQL
>  
SQL
>   create   table  test_2  as   select   distinct   *   from  test;

Table  created.

Elapsed: 
00 : 00 : 07.09
SQL
>  


该方法耗时7.09秒,测试数据库位于服务器上。考虑到服务器和本机位于同一个局域网内,该时间如果在真正的生产环境中应该至上延长1倍以上。

三、使用rowid进行删除:

我们知道在Oracle中,rowid是用来唯一表示一条记录的伪列,任意两条记录的rowid都是不同的,即便内容看起来一模一样。所以我们的思路是:使用表的自连接,查找那些内容相同但rowid不同的记录,即为重复记录。然后随意选择其中一个rowid代表的记录,删除另一条记录。

我们来看一下其中id=1的记录在自连接后的情况:

SQL >   select  a. * , a.rowid, b. * , b.rowid  from  test a, test b  where  a.id  =  b.id  and  a.seq  =  b.seq  and  a
.id 
=   1 ;

        ID        SEQ ROWID                      ID        SEQ ROWID
-- -------- ---------- ------------------ ---------- ---------- ------------------
          1           11  AAAGHIAAJAAAAAKAAA           1           11  AAAGHIAAJAAAAAKAAA
         
1           11  AAAGHIAAJAAAAgQAGX           1           11  AAAGHIAAJAAAAAKAAA
         
1           11  AAAGHIAAJAAAAAKAAA           1           11  AAAGHIAAJAAAAgQAGX
         
1           11  AAAGHIAAJAAAAgQAGX           1           11  AAAGHIAAJAAAAgQAGX

Elapsed: 
00 : 00 : 02.08
SQL
>  


我们看到自连接后的4条记录中有2条的rowid是不同的,说明这2条记录就是重复记录,所以我们可以通过选择其中rowid较大或较小的记录,来删除剩余的记录。但是这种方法的一个很大的缺点就是由于采用了“自连接”,对于像我这样的测试表中有200W条记录的情况,其自连接后的记录数是一个天文数字(其实本人的测试就因为等待过久而不得不取消)。

我们换另外一种方法:

DELETE   FROM  test t1 
 
WHERE  t1.ROWID  NOT   IN  (
     
SELECT   MAX (t2.rowid) 
       
FROM  test t2 
      
WHERE  t1.id  =  t2.id  AND  t1.seq  =  t2.seq);


实践证明,这种方法对大量数据的情况,效率依然是很低的。结果如同上一种方法。假如我们再结合group by呢?

SQL >   DELETE   FROM  test
  
2     WHERE  ROWID  NOT   IN  ( SELECT   MAX (ROWID)  FROM  test  GROUP   BY  id, seq);

这篇关于Oracle开发专题之:删除重复记录的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/906367

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

oracle 11g导入\导出(expdp impdp)之导入过程

《oracle11g导入导出(expdpimpdp)之导入过程》导出需使用SEC.DMP格式,无分号;建立expdir目录(E:/exp)并确保存在;导入在cmd下执行,需sys用户权限;若需修... 目录准备文件导入(impdp)1、建立directory2、导入语句 3、更改密码总结上一个环节,我们讲了

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块

mybatisplus的逻辑删除过程

《mybatisplus的逻辑删除过程》:本文主要介绍mybatisplus的逻辑删除过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录myBATisplus的逻辑删除1、在配置文件中添加逻辑删除的字段2、在实体类上加上@TableLogic3、业务层正常删除即

MybatisPlus中removeById删除数据库未变解决方案

《MybatisPlus中removeById删除数据库未变解决方案》MyBatisPlus中,removeById需实体类标注@TableId注解以识别数据库主键,若字段名不一致,应通过value属... 目录MyBATisPlus中removeBypythonId删除数据库未变removeById(Se