在mysql中关于通过多字段去除重复记录的方法

最近在研究一批网上获取的数据,记录条数约80多万条,单个表大小约 400M,表中重复记录约1/3,在网上查找了些去除重复记录(重复记录保留最小ID值)的sql语句,整理成如下:

DROP TABLE if exists tmp_table1 ;
DROP TABLE if exists tmp_table2 ;
CREATE TEMPORARY TABLE tmp_table1 SELECT id,a1,b1 FROM tb_test2;
CREATE TEMPORARY TABLE tmp_table2 SELECT id,a1,b1 FROM tb_test2;
delete from tb_test2 where (tb_test2.a1,tb_test2.b1) in (select tmp_table1.a1,tmp_table1.b1 from tmp_table1 group by tmp_table1.a1,tmp_table1.b1 having count(*) > 1) 
and tb_test2.id not in (select min(tmp_table2.id) from tmp_table2 group by tmp_table2.a1,tmp_table2.b1 having count(*) > 1);

以上语句记录在数1万左右可以正常执行,但是上20万条左右记录时运行直接无反应(请高手指教一下以上语句是否可以做一下优化!)。

后通过寻求其他途径,思路如下:

创建一个表存储去重后记录的ID值:tb_id;

/*提取无重复的记录及重复记录以最小ID值提取,以a1,b1两个字段作为判断重复记录条件*/
create table tb_id select min(id) AS id from tb_test2 group by a1,b1;

创建一个表存储去重后的记录:tbl_qc;

通过游标方式从原始表中提取记录到去重后的表中,脚本后如下:

drop PROCEDURE if exists procedure_qc;
CREATE PROCEDURE procedure_qc( )
begin
    
/*参数声明*/


    DECLARE num bigint ;  
DECLARE id_dqcl INT; /*id_dqcl:当前处理的id*/

/*参数声明*/


    DECLARE cur CURSOR FOR SELECT id FROM tb_id;
    SELECT COUNT(*) INTO num FROM tb_id;  
    OPEN cur;  
    WHILE i<num DO 
    FETCH cur INTO id_dqcl;


insert into tbl_qc select * from tb_test1 WHERE tb_test1.id = id_dqcl;


    SET i=i+1; 
    END WHILE;  
    CLOSE cur;  
end ;

call procedure_qc();

在两个环境境中执行:

环境1:笔记本 内存8G,CPU i7;耗时:约10小时

环境1:台式机 内存16G,CPU i5;耗时:1159.361s


心得:

标准SQL可以按逻辑写出来,但不一定能有效执行(尽信书不如无书);

性价比:笔记本相对于台式机太垃圾!



  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

myskypb

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值