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.csdn.net/wuyang528378/article/details/49762875
https://zhidao.baidu.com/question/313665822.html