在上一篇文章中,实现了查询重复数据与删除多余重复数据的sql编写:http://blog.csdn.net/u011099093/article/details/78596034;
但是经过导入百万数据测试,查询语句直接卡住没有结果,于是又花了一天时间对sql进行优化,在借鉴了如下地址的方法后,编写出优化后的查重及去重sql:
https://yq.aliyun.com/articles/68224#15
优化查询重复数据:SELECT A,B,C,D,E FROM( SELECT A,B,C,D,E,COUNT(*) OVER(PARTITION BY A,B,C )AS tmp FROM TABLE WHERE CONDITION) t WHERE t.tmp>=2;
优化处理重复数据:
DELETE FROM TABLE WHERE ID NOT IN(SELECT ID FROM
(SELECT MIN(ID) ID,A,B,C FROM TABLE WHERE CONDITION GROUP BY A,B,C HAVING COUNT(*)>1) C)
AND ID IN( SELECT ID FROM
(SELECT ID,COUNT(*) OVER(PARTITION BY A,B,C) AS tmp FROM TABLE WHERE CONDITION)t WHERE t.tmp>=2);
对于over partition的用法我真的不是很了解,而上述地址中对重复 数据清洗讲的比较详细,有兴趣的同学可移步去看看。
-------------------------------------------11-29更新-------------------------------------------------------
经过比较发现使用row_number()函数替换count(*) 查重变得更快速,而这里查出的重复数据发生了改变,不再是所有重复数据,而是每种都保留1条未查出,所以对应的处理SQL也会发生改变:
DELETE FROM TABLE WHERE ID IN( SELECT ID FROM
(SELECT ID,ROW_NUMBER() OVER(PARTITION BY A,B,C) AS tmp FROM TABLE WHERE CONDITION)t WHERE t.tmp>=2);
ROW_NUMBER是一个对所查数据编号排序的函数所以如果上述查重及去重语句如果能在OVER(PARTITION BY A,B,C) AS tmp 中添加order by进行按字段排序,结果将更加准确;
而如果使用count(*) 或count(1)时,partition by A,B,C 后跟order by D desc等排序字段,查询的也是经过排序后的重复数据。