MYSQL数据去重

 我们用的数据库是mysql,偶尔会因为程序处理上的方便或者sql未优化而增加了一些重复数据,最后需要对这些重复的数据进行删除

对于数据量不大的时候我一般用not in的方式来处理,或者删全表,导出不重复的数据,然后再insert的方式,网上也提供了很多方式,但是很多都需要执行很长时间,而且资源占用很多,对于数据量大的时候被DBA否决了

比如表tb1中的结构为

id    param1    param2    param3    date

其中id为主键,param为需要去重的项

 

一、not in的方式(可以用一条sql或者用脚本来处理,但是一条sql会执行时间太长)

DELETE FROM tb1 WHERE id not in (SELECT id FROM tb1 GROUP BY param1, param2, param3);

或者当数据量大的时候,一维或者多维分步操作

DELETE FROM tb1 WHERE param1='param1' AND id not in (SELECT id FROM tb1 WHERE param1='param1' GROUP BY param1, param2, param3);

notin的方式我在冗余时数据总量在百万级的时候,好像还行,问题也不是很大,但是当上千万量级的时候,DBA就开始过来找我了

 

二、删除数据,然后插入distinct数据

SELECT param1, param2, param3, date FROM tb1 GROUP BY param1, param2, param3;

DELETE FROM tb1;

INSERT INTO tb1 (param1, param2, param3, date) VALUES ......

DBA不太同意我这种方式

DBA建议我用in的方式,于是我就想到了用shell进行处理

 

三、用shell脚本帮忙筛选然后用主键in的方式来删除

SELECT id FROM tb1 GROUP BY param1, param2, param3 > ids.csv

SELECT id FROM tb1 >> ids.csv

cat ids.csv|sort|uniq -c| awk '{if($1==1) print $2}' > delete_ids.csv

DELETE FROM tb1 WHERE id IN delete_ids

或者分维度处理也行,减小数据库压力

 

这种方式ids.csv文件中先输入了去重param1,param2,param3的id,然后再把所有id再次加入进去,这样我们需要保留的id的count就为2了,利用shell的sort和uniq工具,就可以筛选出来需要delete掉的id了,于是大功告成了,

我采用的是分一个维度来删的(也就是分不同的param1来处理),最终1.2y数据中删除4kw的冗余,轻轻松松就解决掉了,DBA毫无压力(param1建了索引)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章