- 浏览: 107027 次
- 来自: ...
最新评论
表demo是重复拷贝自dba_objects,有88万左右,不重复的是27323,没有索引
方法一:delete from demo a where a.rowid <> (select max(rowid) from demo b where
b.object_id=a.object_id);
耗时:几个小时以上
方法一:delete from demo a where a.rowid <> (select max(rowid) from demo b where
b.object_id=a.object_id);
耗时:几个小时以上
方法二: delete from demo where rowid in
(select rid from
(select rowid rid,row_number() over(partition by object_id order by rowid) rn
from demo)
where rn <> 1 );
耗时:30秒
方法三: create table demo2 as
select object_id,owner... from
(select demo.*,row_number() over(partition by object_id order by rowid) rn from demo)
where rn = 1;
truncate table demo; insert into demo select * from demo2; drop table demo2;
共耗时: 10秒,适合大数据量的情况,产生更少回滚量;
评论
2 楼
czllfy
2007-03-16
没有主键(Primary Key)约束保护的表格可能会让重复的数据行被插入进来。查找这种重复数据的传统方式是通过GROUP BY和HAVING关键字进行查询。在根据关键列把数据分组并计算每个组里的行数之后,有一个以上成员的组就是带有重复数据的组。
尽管发现这样的数据行很容易,但是解决这一问题却十分耗时。在Oracle里,独特的ROWID伪列(pseudocolumn)意味着没有两个列是真正一模一样的。你可以总是利用删除(DELETE)查询来参考一个以外的所有ROWID,以便删除所有的重复数据。这非常有效——如果你没有太多的重复数据需要删除的话。而Oracle 9i里引入的分析函数给予了我们一种更简单的方式来进行这种清除工作。
ROW_NUMBER()分析函数与ROWNUM伪列相似的地方在于它们都能够给输出的行编号。但是ROWNUM给出的是整个数据列完整的序列,而ROW_NUMBER会在我们在数据列里定义的每个分区里把编号重新设置回1。这样做的结果是不仅能够很容易就看到哪个组里有多个成员,还能够确切知道需要删除哪个行。
分析查询的格式是:
Functionname (arguments) OVER (PARTITION BY columns ORDER BY columns)
现在让我们假设在创建SCOTT.EMP表格副本的时候出现了错误,所有的行都被输入了两遍。尝试加入一个主键约束会失败,因为数据已经出现了重复。列表A显示了这一过程,为了清楚说明问题,它被分成两个阶段:
Listing A SQL> -- Will you just LOOK at this table? Lots of duplicates!
SQL>
SQL> SELECT empno, ename
2 FROM emp2
3 ORDER BY empno;
EMPNO ENAME
---------- ----------
7369 SMITH
7369 SMITH
7499 ALLEN
7499 ALLEN
7521 WARD
7521 WARD
7566 JONES
7566 JONES
7654 MARTIN
7654 MARTIN
7698 BLAKE
7698 BLAKE
7782 CLARK
7782 CLARK
7788 SCOTT
7788 SCOTT
7839 KING
7839 KING
7844 TURNER
7844 TURNER
7876 ADAMS
7876 ADAMS
7900 JAMES
7900 JAMES
7902 FORD
7902 FORD
7934 MILLER
7934 MILLER
28 rows selected.
SQL> -- First step: number the duplicates of each empno
SQL>
SQL> SELECT ROWID, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) rn
2 FROM emp2;
ROWID RN
------------------ ----------
AAAM1UAAEAAAAGsAAA 1
AAAM1UAAEAAAAGuAAA 2
AAAM1UAAEAAAAGuAAB 1
AAAM1UAAEAAAAGsAAB 2
AAAM1UAAEAAAAGsAAC 1
AAAM1UAAEAAAAGuAAC 2
AAAM1UAAEAAAAGuAAD 1
AAAM1UAAEAAAAGsAAD 2
AAAM1UAAEAAAAGsAAE 1
AAAM1UAAEAAAAGuAAE 2
AAAM1UAAEAAAAGsAAF 1
AAAM1UAAEAAAAGuAAF 2
AAAM1UAAEAAAAGsAAG 1
AAAM1UAAEAAAAGuAAG 2
AAAM1UAAEAAAAGsAAH 1
AAAM1UAAEAAAAGuAAH 2
AAAM1UAAEAAAAGsAAI 1
AAAM1UAAEAAAAGuAAI 2
AAAM1UAAEAAAAGsAAJ 1
AAAM1UAAEAAAAGuAAJ 2
AAAM1UAAEAAAAGsAAK 1
AAAM1UAAEAAAAGuAAK 2
AAAM1UAAEAAAAGsAAL 1
AAAM1UAAEAAAAGuAAL 2
AAAM1UAAEAAAAGsAAM 1
AAAM1UAAEAAAAGuAAM 2
AAAM1UAAEAAAAGuAAN 1
AAAM1UAAEAAAAGsAAN 2
28 rows selected.
SQL> -- Now, use that as an inline view, and select just the dups
SQL> -- We're including the row number, it won't be in the final query
SQL>
SQL> SELECT ROWID, rn
2 FROM
3 (SELECT ROWID, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) rn
4 FROM emp2)
5 WHERE rn > 1;
ROWID RN
------------------ ----------
AAAM1UAAEAAAAGuAAA 2
AAAM1UAAEAAAAGsAAB 2
AAAM1UAAEAAAAGuAAC 2
AAAM1UAAEAAAAGsAAD 2
AAAM1UAAEAAAAGuAAE 2
AAAM1UAAEAAAAGuAAF 2
AAAM1UAAEAAAAGuAAG 2
AAAM1UAAEAAAAGuAAH 2
AAAM1UAAEAAAAGuAAI 2
AAAM1UAAEAAAAGuAAJ 2
AAAM1UAAEAAAAGuAAK 2
AAAM1UAAEAAAAGuAAL 2
AAAM1UAAEAAAAGuAAM 2
AAAM1UAAEAAAAGsAAN 2
14 rows selected.
SQL> -- Now we DELETE all the rows in that set
SQL>
SQL> DELETE FROM emp2
2 WHERE ROWID IN
3 (SELECT ROWID
4 FROM (SELECT ROWID,
5 ROW_NUMBER() OVER (PARTITION BY empno ORDER BY EMPNO) rn
6 FROM emp2)
7 WHERE rn > 1);
14 rows deleted.
SQL> commit;
Commit complete.
SQL> -- Show the de-dup'ed table
SQL>
SQL> SELECT empno, ename
2 FROM emp2;
EMPNO ENAME
---------- ----------
7369 SMITH
7521 WARD
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7499 ALLEN
7566 JONES
7934 MILLER
首先是一个分析查询,通过empno行来分区;它使用ROW_NUMBER()给每个分区进行编号。如果没有重复的内容,分区就只有一个行,编号是“1”。但是,如果存在重复,那么它们就会被编上2、3等号码。这个查询还会返回我们用来唯一识别数据行的ROWID。第一个查询然后就被用作另外一个查询的内联视图,这第二个查询使用一个WHERE子句过滤掉“1”行,只返回重复的内容。最后,一个DELETE语句通过第二个查询使用IN操作符来删掉所有的重复内容。
就和所有的大规模DELETE一样,你需要记住的是,最好把想要保留的行(也就是说那些ROW_NUMBER为1的行)保存到一个新的表格里。INSERT所造成的负载要比DELETE小得多。
尽管发现这样的数据行很容易,但是解决这一问题却十分耗时。在Oracle里,独特的ROWID伪列(pseudocolumn)意味着没有两个列是真正一模一样的。你可以总是利用删除(DELETE)查询来参考一个以外的所有ROWID,以便删除所有的重复数据。这非常有效——如果你没有太多的重复数据需要删除的话。而Oracle 9i里引入的分析函数给予了我们一种更简单的方式来进行这种清除工作。
ROW_NUMBER()分析函数与ROWNUM伪列相似的地方在于它们都能够给输出的行编号。但是ROWNUM给出的是整个数据列完整的序列,而ROW_NUMBER会在我们在数据列里定义的每个分区里把编号重新设置回1。这样做的结果是不仅能够很容易就看到哪个组里有多个成员,还能够确切知道需要删除哪个行。
分析查询的格式是:
Functionname (arguments) OVER (PARTITION BY columns ORDER BY columns)
现在让我们假设在创建SCOTT.EMP表格副本的时候出现了错误,所有的行都被输入了两遍。尝试加入一个主键约束会失败,因为数据已经出现了重复。列表A显示了这一过程,为了清楚说明问题,它被分成两个阶段:
Listing A SQL> -- Will you just LOOK at this table? Lots of duplicates!
SQL>
SQL> SELECT empno, ename
2 FROM emp2
3 ORDER BY empno;
EMPNO ENAME
---------- ----------
7369 SMITH
7369 SMITH
7499 ALLEN
7499 ALLEN
7521 WARD
7521 WARD
7566 JONES
7566 JONES
7654 MARTIN
7654 MARTIN
7698 BLAKE
7698 BLAKE
7782 CLARK
7782 CLARK
7788 SCOTT
7788 SCOTT
7839 KING
7839 KING
7844 TURNER
7844 TURNER
7876 ADAMS
7876 ADAMS
7900 JAMES
7900 JAMES
7902 FORD
7902 FORD
7934 MILLER
7934 MILLER
28 rows selected.
SQL> -- First step: number the duplicates of each empno
SQL>
SQL> SELECT ROWID, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) rn
2 FROM emp2;
ROWID RN
------------------ ----------
AAAM1UAAEAAAAGsAAA 1
AAAM1UAAEAAAAGuAAA 2
AAAM1UAAEAAAAGuAAB 1
AAAM1UAAEAAAAGsAAB 2
AAAM1UAAEAAAAGsAAC 1
AAAM1UAAEAAAAGuAAC 2
AAAM1UAAEAAAAGuAAD 1
AAAM1UAAEAAAAGsAAD 2
AAAM1UAAEAAAAGsAAE 1
AAAM1UAAEAAAAGuAAE 2
AAAM1UAAEAAAAGsAAF 1
AAAM1UAAEAAAAGuAAF 2
AAAM1UAAEAAAAGsAAG 1
AAAM1UAAEAAAAGuAAG 2
AAAM1UAAEAAAAGsAAH 1
AAAM1UAAEAAAAGuAAH 2
AAAM1UAAEAAAAGsAAI 1
AAAM1UAAEAAAAGuAAI 2
AAAM1UAAEAAAAGsAAJ 1
AAAM1UAAEAAAAGuAAJ 2
AAAM1UAAEAAAAGsAAK 1
AAAM1UAAEAAAAGuAAK 2
AAAM1UAAEAAAAGsAAL 1
AAAM1UAAEAAAAGuAAL 2
AAAM1UAAEAAAAGsAAM 1
AAAM1UAAEAAAAGuAAM 2
AAAM1UAAEAAAAGuAAN 1
AAAM1UAAEAAAAGsAAN 2
28 rows selected.
SQL> -- Now, use that as an inline view, and select just the dups
SQL> -- We're including the row number, it won't be in the final query
SQL>
SQL> SELECT ROWID, rn
2 FROM
3 (SELECT ROWID, ROW_NUMBER() OVER (PARTITION BY empno ORDER BY empno) rn
4 FROM emp2)
5 WHERE rn > 1;
ROWID RN
------------------ ----------
AAAM1UAAEAAAAGuAAA 2
AAAM1UAAEAAAAGsAAB 2
AAAM1UAAEAAAAGuAAC 2
AAAM1UAAEAAAAGsAAD 2
AAAM1UAAEAAAAGuAAE 2
AAAM1UAAEAAAAGuAAF 2
AAAM1UAAEAAAAGuAAG 2
AAAM1UAAEAAAAGuAAH 2
AAAM1UAAEAAAAGuAAI 2
AAAM1UAAEAAAAGuAAJ 2
AAAM1UAAEAAAAGuAAK 2
AAAM1UAAEAAAAGuAAL 2
AAAM1UAAEAAAAGuAAM 2
AAAM1UAAEAAAAGsAAN 2
14 rows selected.
SQL> -- Now we DELETE all the rows in that set
SQL>
SQL> DELETE FROM emp2
2 WHERE ROWID IN
3 (SELECT ROWID
4 FROM (SELECT ROWID,
5 ROW_NUMBER() OVER (PARTITION BY empno ORDER BY EMPNO) rn
6 FROM emp2)
7 WHERE rn > 1);
14 rows deleted.
SQL> commit;
Commit complete.
SQL> -- Show the de-dup'ed table
SQL>
SQL> SELECT empno, ename
2 FROM emp2;
EMPNO ENAME
---------- ----------
7369 SMITH
7521 WARD
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7499 ALLEN
7566 JONES
7934 MILLER
首先是一个分析查询,通过empno行来分区;它使用ROW_NUMBER()给每个分区进行编号。如果没有重复的内容,分区就只有一个行,编号是“1”。但是,如果存在重复,那么它们就会被编上2、3等号码。这个查询还会返回我们用来唯一识别数据行的ROWID。第一个查询然后就被用作另外一个查询的内联视图,这第二个查询使用一个WHERE子句过滤掉“1”行,只返回重复的内容。最后,一个DELETE语句通过第二个查询使用IN操作符来删掉所有的重复内容。
就和所有的大规模DELETE一样,你需要记住的是,最好把想要保留的行(也就是说那些ROW_NUMBER为1的行)保存到一个新的表格里。INSERT所造成的负载要比DELETE小得多。
1 楼
yiding_he
2007-03-15
5555 好想了解怎么回事,不过看不懂,兄台能否讲解一下?
发表评论
文章已被作者锁定,不允许评论。
-
Oracle sql 性能优化调整
2009-11-05 08:26 4888Oracle sql 性能优化调整 1. 选用适合的ORA ... -
ORACLE SQL性能优化系列
2009-11-05 08:24 19431. 减少访问数据库的次数 当执行每条SQL语句时, ... -
Oracle中索引的使用 索引性能优化调整
2009-11-05 08:22 3913索引是由Oracle维护的可 ... -
oracle性能优化技巧
2009-11-05 08:22 12261.选用适合的ORACLE优化器 ORACLE的优化 ... -
Oracle性能优化的基本方法概述
2009-11-05 08:21 13971)设立合理的性能优化目标。 2)测量并记录当前性能。 3)确 ... -
查看oracle 某个表的所有字段名
2007-04-04 19:15 11242select column_name from u ... -
Oracle 序列的创建和使用
2007-03-30 21:52 16334创建序列 create sequence seq_a minv ... -
Oracle中插入图片并显示(用BLOB类型)
2007-03-30 21:43 6448要在oracle里面存入图片 用 blob类型 首先在数据 ... -
图片上传到oracle数据库的blob字段
2007-03-29 08:54 3340Ry_jbxx_list.jsp <%String h ... -
Oracle 函数大全
2007-03-15 20:42 864SQL中的单记录函数 1.ASCII 返回与指定的字符对应 ...
相关推荐
ORACLE删除重复数据的一种高效的方法.
提出一种无须可信第三方的自适应重复删除方法。利用完美散列函数检查数据的流行度,使用口令认证密钥交换协议与同态加密安全传递数据的加密密钥,在保证用户数据隐私的前提下进行安全的重复数据删除。与现有其他方案...
重复数据删除是一种数据缩减技术,通常用于基于磁盘的备份系统,旨在减少存储系统中使用的存储容量。它的工作方式是在某个时间周期内查找不同文件中不同位置的重复可变大小数据块。重复的数据块用指示符取代。高度...
本文实例讲述了JavaScript实现删除数组重复元素的5种常用高效算法。分享给大家供大家参考,具体如下: 这里就 js 如何实现数组去重整理出5种方法,并附上演示Demo 以及 源码。 1.遍历数组法 最简单的去重方法, 实现...
AE:一种用于带宽快速高效重复数据删除的非对称极值内容定义分块算法
分析报告编写方法总结 前言 什 么 是 数 据 分 析 报 告 数据分析报告是根据数据分析原理和 方法,运用数据来反映、研究和分析某项事 物的现状、问题、原因、本质和规律,并得 出结论 ,提出解决办法的一种文体。...
重复数据删除是一种数据缩减技术,通常用于基于磁盘的备份系统,旨在减少存储系统中使用的存储容量。它的工作方式是在某个时间周期内查找不同文件中不同位置的重复可变大小数据块。重复的数据块用指示符取代。高度...
zVault备份解决方案 zVault是一种高效的重复数据消除备份解决方案,支持客户端加密,压缩和远程存储备份数据。主要特点节省空间的存储每个文件都分为多个块。 内容定义的组块和组块指纹确保每个组块仅存储一次。 ...
概念 大数据技术,是指一种在不使用传统随机理论进行数据分析的情况下对数据进行集成分析和处理的方法,主要是在数据处理方面面临挑战。由于实际的生产和寿命,会生成并存储大量数据,这些数据可以表征该过程。您会...
12.2.3 怎样使用一种独特的顺序对数据项进行排序,它既不是增序也不是降序 282 12.2.4 怎样将数据透视表转换为硬数据 283 12.2.5 有简单的方法填充行字段留下的空单元格吗 283 12.2.6 简单的方法填充许多列...
12.2.3 怎样使用一种独特的顺序对数据项进行排序,它既不是增序也不是降序 282 12.2.4 怎样将数据透视表转换为硬数据 283 12.2.5 有简单的方法填充行字段留下的空单元格吗 283 12.2.6 简单的方法填充许多列...
12.2.3 怎样使用一种独特的顺序对数据项进行排序,它既不是增序也不是降序 282 12.2.4 怎样将数据透视表转换为硬数据 283 12.2.5 有简单的方法填充行字段留下的空单元格吗 283 12.2.6 简单的方法填充许多列...
以及分布式数据库HBase在存储文件名重复度和类似度高时产生访问热点的问题,结合样本数据集的特点、类型,提出一种面向样本数据集存取优化方案,优化样本数据集中小文件的写入、读取、添加、删除和替换策略。...
6.其它操作:去掉重复的数据,删除鼠标处的坏数据,去掉最后一个数据等等. 主要功能: 1.可选择精确使用鼠标点击或拖动数据获取图表上的数据; 2.增强的放大镜功能可使数据获取更精确; 3.可剔去冗余、重复和误操作...
这里介绍一种高效数组去重的方法:根据JS对象的特性去除数组中重复项的方法。 一、JS对象的特性(本文中所使用的特性):key始终唯一 引例:说明对象key值的唯一性,即当重新给js已有属性赋值的时候,实际上是覆盖了...
12.2.3 怎样使用一种独特的顺序对数据项进行排序,它既不是增序也不是降序 282 12.2.4 怎样将数据透视表转换为硬数据 283 12.2.5 有简单的方法填充行字段留下的空单元格吗 283 12.2.6 简单的方法填充许多列...
6.其它操作:去掉重复的数据,删除鼠标处的坏数据,去掉最后一个数据等等. 下载地址: http://download.csdn.net/detail/rumswell/4249113 主要功能: 1.可选择精确使用鼠标点击或拖动数据获取图表上的数据; 2.增强...
另外,该工具能够以一种高效的方式完成新入库的数据的导出。 1.3-1.5版改动不大,主要都在于界面以及对话框的改进,中间版本不再放出。 注:当前版本中并没有对数据进行排序处理,也就是说,导入到数据库或文件...
另外,该工具能够以一种高效的方式完成新入库的数据的导出。 由于1.2版与1.0之间周期很短,故决定不发出1.1版。 本版本采用了更为友好的界面,并修改了导出文件的实现,现在的导出只导出新入库的数据。另外,改进了...