1. 程式人生 > >MySQL表上億級資料量實現刪除重複記錄

MySQL表上億級資料量實現刪除重複記錄

上週從資料採集部門拿到一批400份的json檔案,每個檔案裡30w+的json物件,物件裡有uid,對重複的uid,需要去重下.

電腦配置4核8G 

廢話不多說,直接上乾貨.

1.建立表datatest5

CREATE TABLE `datatest5` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `val` varchar(16) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `val` (`val`)
) ENGINE=InnoDB AUTO_INCREMENT=57667550 DEFAULT CHARSET=utf8;

1.1   id是表的主鍵自增,val是需要去重的資料,為val建立索引  (建立索引,建立索引,建立索引)!!!

1.2   將12000w的uid從入到datatest5表中.(剛開始的時候20分鐘跑完,建立索引後大概3個小時多,而且磁碟一直80%多)

2. 設定innodb緩衝池大小

2.1 show variables like "%_buffer%";-- 先檢視下

    SET GLOBAL innodb_buffer_pool_size=8388608; -- 系統值(儲存起來,結束後修改回來)
2.2 SET GLOBAL innodb_buffer_pool_size=109051904;-- 修改值

3. 查詢datatest5表總資料量

 SELECT COUNT(0) ct from datatest5; -- 127351895

4. 查詢分組後的表條數也就是我們的需求

SELECT COUNT(DISTINCT val) ct FROM datatest5;-- 97267435

5.建立datatest5_1表資料為重複的val和其對應id最大值

CREATE TABLE datatest5_1 AS ( SELECT a.val, MAX(a.id) maxid FROM datatest5 a, ( SELECT val FROM datatest5 GROUP BY val HAVING count(val) > 1 ) b WHERE a.val = b.val GROUP BY val ) ;

6.刪除原datatest5表中所有重複的資料

DELETE a FROM datatest5 a,datatest5_1 a5 WHERE a.id<a5.maxid AND a.val=a5.val ;

7.統計表datatest5中的資料

SELECT COUNT(0) ct from datatest5 ; -- 97267435

8.對比第7步和第4步的結果,若一樣就證明刪除重複資料成功.

一共用時53分鐘.

注意: 1.表一定要給重複值的欄位建立索引 2.資料清洗完之後磁碟還是佔用80%多的話,可以恢復innodb緩衝池大小或者將資料轉存檔案並刪除datatest5表就好了.

 

借鑑文章

https://blog.qxzzf.com/135

https://blog.csdn.net/wuyang528378/article/details/49762875

https://zhidao.baidu.com/question/313665822.html