刪除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 左右

 

結論

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


免責聲明!

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



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