建设工作站服务器
本节介绍了两种查询和删除重复记录的方法:一种是使用rowid辅助完成的,另一种是借助分析函数完成的。
这两种方法的执行效率比其他方法更高。 尽管如此,这两种方法之间还是有本质的性能差异。 通过实验向您展示这两种方法,并说明其本质的区别。
1 .建立实验用表,初始化一些样本数据
sec@ora10gcreatetablet(xnumber,yvarchar2(10 );
sec@ora10ginsertintotvalues(1,\\&; quot; sec\\&; quot;
sec@ora10ginsertintotvalues(2,\\&; quot; Andy01\\\&; quot;
sec@ora10ginsertintotvalues(2,\\&; quot; Andy02\\\&; quot;
sec@ora10ginsertintotvalues(3,\\&; quot; Anna\\\&; quot;
sec@ora10ginsertintotvalues(4,\\&; quot; Anna\\\&; quot;
sec@ora10ginsertintotvalues(5,\\&; quot; John\\&; quot;
sec@ora10g commit;
sec @ secooleranalyzetabletcomputestatisticsfortableforallindexesforallindexedcolumns;
已分析。
sec@ora10g select * from t;
X Y
——---- ——3————
1秒
2 Andy01
2 Andy02
3 Anna
4 Anna
5约翰
6已选择。
使用rowid辅助查询和删除重复记录的第一种方法
1 )查询重复记录
sec@ora10g SELECT *
2 FROM t t1
3whereT1.rowid(selectmin ) T2.rowid ) )。
4 FROM t t2
5 WHERE t1.x=t2.x )
6 /
X Y
——---- ——3————
2 Andy02
btw :如果要查询同时包含重复的" x "和" y "字段,可以在上面的子查询中添加另一个条件" AND t1.y=t2.y "
2 )删除重复记录
只需将上述查询语句改写为删除语句,即可完成删除任务。
sec@ora10g DELETE FROM t t1
2whereT1.rowid(selectmin ) T2.rowid ) )。
3 FROM t t2
4 WHERE t1.x=t2.x )
5 /
1低删除。
此时,您可以看到x字段的重复项已经被删除。
sec@ora10g select * from t;
X Y
——---- ——3————
1秒
2 Andy01
3 Anna
4 Anna
5约翰
3 .使用分析函数辅助查询和删除重复记录的第二种方法
1 )使用分析函数可以快速定位重复记录。 在以下结果中,rn值大于1的行表示重复行:
sec@ora10g SELECT t1.x,
2 t1.y,
3row_number(over ) partitionbyT1.xorderbyT1.rowid ) rn
4 FROM t t1
5 /
X Y RN
——-- ————3———— -
1秒1
2安迪01
2安迪02
3 Anna 1
4 Anna 1
5约翰1
6已选择。
2 )进而使用上述rn结果作为辅助条件时,可以得到重复记录内容
sec@ora10g SELECT t2.x,t2.y
2从( select t1.x,
3 t1.y,
4 ROW_NUMBER ( ) over ) partitionbyT1.xorderbyT1.rowid ) rn
5 FROM t t1 ) t2
6 WHERE t2.rn 1
7 /
X Y
——---- ——3————
2 Andy02
3 )删除方法
)第一个方法是用rowid构建并删除delete语句,效率低下。
sec @ or a10 gdeletefromtwhererowidin (
2选择行
3从( select t1.x,
4 t1.y,
5 ROW_NUMBER ( ) over ) partitionbyT1.xorderbyT1.rowid ) rn
6 FROM t t1 ) t2
7 WHERE t2.rn 1
8 ) )。
9 /
1低删除。
)第二种方法可以通过构建中间表t1的方法来实现。 这是一种非常高效的脱氢方法,建议在具有大量数据的数据库环境中使用。
sec@ora10g create table t1 as
2 SELECT t2.x,t2.y
3从( select t1.x,
4 t1.y,
5 ROW_NUMBER ( ) over ) partitionbyT1.xorderbyT1.rowid ) rn
6 FROM t t1 ) t2
7 WHERE t2.rn=1
8 /
表格创建。
sec@ora10g drop table t;
表格折叠。
sec @ or a10 galter table t1 rename tot;
表格警报。
sec@ora10g select * from t;
X Y
——---- ——3————
1秒
2 Andy01
3 Anna
4 Anna
5约翰
4 .比较两种查询方法的执行计划,得出两种方法内在性能差异的来源。
1 )使用rowid辅助查询的初始执行计划如下
sec@ora10g set autot trace exp
sec@ora10g SELECT *
2 FROM t t1
3whereT1.rowid(selectmin ) T2.rowid ) )。
4 FROM t t2
5 WHERE t1.x=t2.x )
6 /
执行计划
————————————335433543——3——3——3——3——333334 -
Plan hash value: 3924487551
————————3——————————————3——3——3——3——33—— -
| id|rows|cost ( % CPU ) |
————————3——————————————3——3——3——3——33—— -
|0|selectstatement|||5|55|6(0)| 00:00:01 |
| *1|过滤器|||||
|2|tableaccessfull|t|6|66|3(0)| 00:00:01 |
| 3 | SORT AGGREGATE | | 1 | 11 | | |
| *4| tableaccessfull|t|1|11|3|0|00:00:01 |
————————3——————————————3——3——3——3——33—— -
predicate information ( identifiedbyoperationid ) :
————————3354——335433543354335433543354——3——33334 -
1filter ( t1.rowid ) select min ( T2.rowid ) FROM T T2 WHERE
T2.X=:B1 )
4filter ( T2.x=:B1 ) ) )
2 )使用第二个分析函数执行查询的计划如下
sec@ora10g SELECT t1.x,
2 t1.y,
3row_number(over ) partitionbyT1.xorderbyT1.rowid ) rn
4 FROM t t1
5 /
执行计划
————————————335433543——3——3——3——3——333334 -
Plan hash value: 2335850315
——3354335433543354——33543354——————3354————3——3——————333——4 -
| id|rows|cost ( % CPU ) |
——3354335433543354——33543354——————3354————3——3——————333——4 -
|0|选择状态|||6| 66|4|25|00:00:01 |
|1| window sort|||6|66|4|25|00:00:01 |
|2|tableaccessfull|t|6|66|3(0)| 00:00:01 |
——3354335433543354——33543354——————3354————3——3——————333——4 -
3 )通过比较以上两个执行计划,可以得出以下结论
第一种方法采用两次TABLE ACCESS FULL,第二种方法采用一次TABLE ACCESS FULL。
从执行计划中可以看出,使用分析函数的方法更有效率。
5 .总结
在DBA数据库的维护工作中,经常不可避免地会出现删除重复记录的问题。 从包含大量数据的数据库中删除重复记录是一项困难的任务,如果方法选择错误,则很可能难以完成任务。
这里介绍的两种方法都比较有效率,所以细节请慢慢品尝。
完成任务的手段和方法很多,只有将维护时间和对生产数据库的冲击降到最低的方法才是可以接受的正确方法。
好路克。
— The End —
详情请访问云服务器、域名注册、虚拟主机的问题,请访问西部数码代理商官方网站: www.chenqinet.cn