mysql數據去除重復及相關優化(轉)


由於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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM