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建了索引)

 

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