1. 程式人生 > 其它 >刪除MySQL資料庫重複資料保留一條

刪除MySQL資料庫重複資料保留一條

在開發中,遇到了多次需要刪除重複資料並且根據條件保留一條的情況,因此就做個總結。

以此表為例:

-- 使用者表 
create table t_user
(
    id        bigint auto_increment
        primary key,
    name      varchar(20) not null,
    password  varchar(20) not null,
    lessee_id int         not null
)
    comment '使用者表';
create index idx_name
    on t_user (name);

原始資料:

三種方式

目標:刪除重複資料,保留ID最大的一條
-- 第一種
DELETE t1
FROM t_user t1,
     t_user t2
WHERE t1.lessee_id = t2.lessee_id
  AND t1.name = t2.name
  AND t1.id < t2.id;

-- 第二種
delete
from t_user
where id not in (
    (select t1.max_id
     from (select max(id) as max_id from t_user group by name, lessee_id having
count(1) > 1) t1)) and (lessee_id, name) in (select t2.lessee_id, t2.name from (select lessee_id, name from t_user group by name, lessee_id having count(1) > 1) t2); -- 第三種 delete from t_user where id not in (select * from (select max(id) from t_user group by name, lessee_id) t2);

效率對比

往表中插入測試資料:

DELIMITER $$
CREATE PROCEDURE pro_copy()
BEGIN
SET @i=1; -- 起始
WHILE @i<=500000 DO
INSERT INTO t_user(NAME,password,lessee_id) VALUES(CONCAT('user',@i),'123',5); -- 拼接USER 和i值
SET @i=@i+1; -- 防止成為死迴圈
END WHILE; -- 結束迴圈
END $$ -- 結束自定義結束符
DELIMITER ;
call pro_copy(); -- 呼叫函式

方式

20w資料去重耗時(name無索引)

50w資料去重耗時(name有索引)

第一種

3min以上

3s 523ms 左右

第二種

6s 172ms 左右

16s 726ms 左右

第三種

3s 868ms 左右

13s 656ms 左右

結論

在查詢條件有索引的情況下,選擇第一種去重方式,沒有索引的情況下選擇第三種。