由於mysql不支持同時對一張表進行操作,即子查詢和要進行的操作不能是同一張表,因此需要通過臨時表中專以下。
1、單字段重復
生成臨時表,其中uid是需要去重的字段
create table tmp_uid as (select uid from user_info group by uid having count(uid)) create table tmp_id as (select min(id) from user_info group by uid having count()uid)
數量量大時一定要為uid創建索引
alter table tmp_uid add index 索引名 (字段名) alter table tmp_id add index 索引名 (字段名)
刪除多余的重復數據,保留重復數據中id最小的
delete from user_info where id not in (select id from tmp_id) and uid in (select uid from tmp_uid)
2、多字段重復
如以上由於uid的重復間接導致了relationship中的記錄重復,所以繼續去重。
2.1 一般方法
基本的同上面:
生成臨時表
create table tmp_relation as (select source,target from relationship group by source,target having count(*)>1) create table tmp_relationship_id as (select min(id) as id from relationship group by source,target having count(*)>1)
創建索引
alter table tmp_relationship_id add index 索引名(字段名)
刪除
delete from relationship where id not in (select id from tmp_relationship_id) and (source,target) in (select source,target from relationship)
2.2 快速方法
實踐中發現上面的刪除字段重復的方法,由於沒有辦法為多字段重建索引,導致數據量大時效率極低,低到無法忍受。最后,受不了等了半天沒反應的狀況,本人決定,另辟蹊徑。
考慮到,估計同一記錄的重復次數比較低。一般為2,或3,重復次數比較集中。所以可以嘗試直接刪除重復項中最大的,直到刪除到不重復,這時其id自然也是當時重復的里邊最小的。
大致流程如下:
(1)、選擇每個重復項中的id最大的一個記錄
create table tmp_relation_id2 as (select max(id) from relationship group by source,target having count(*)>1)
(2)、創建索引(僅需在第一次時執行)
alter table tmp_relation_id2 add index 索引名 (字段名)
(3)、刪除重復項中id最大的記錄
delete from relationship where id in (select id from tmp_relation_id2)
(4)、刪除臨時表
drop table tmp_relation_id2
重復上述步驟(1),(2),(3),(4),直到創建的臨時表中不存在記錄就結束(對於重復次數的數據,比較高效)
本文章轉自 http://www.cnblogs.com/rainduck/archive/2013/05/15/3079868.html