MySQL 大批量插入,如何过滤掉重复数据?

发表于:2021-9-16 09:40

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:佚名    来源:Java编程爱好者

  加班原因是上线,解决线上数据库存在重复数据的问题,发现了程序的bug,很好解决,有点问题的是,修正线上的重复数据。
  线上库有6个表存在重复数据,其中2个表比较大,一个96万+、一个30万+,因为之前处理过相同的问题,就直接拿来了上次的Python去重脚本,脚本很简单,就是连接数据库,查出来重复数据,循环删除。
  emmmm,但是这个效率嘛,实在是太低了,1秒一条,重复数据大约2万+,预估时间大约在8个小时左右。
  盲目依靠前人的东西,而不去自己思考是有问题的!总去想之前怎么可以,现在怎么不行了,这也是有问题的!我发现,最近确实状态不太对,失去了探索和求知的欲望,今天算是一个警醒,颇有迷途知返的感觉。
  言归正传,下面详细介绍去重步骤。
  CREATE TABLE `animal` (  
    `id` int(11) NOT NULL AUTO_INCREMENT,  
    `name` varchar(20) DEFAULT NULL,  
    `age` int(11) DEFAULT NULL,  
    PRIMARY KEY (`id`)  
  ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;  
  INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('1', 'cat', '12');  
  INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('2', 'dog', '13');  
  INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('3', 'camel', '25');  
  INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('4', 'cat', '32');  
  INSERT INTO `pilipa_dds`.`student` (`id`, `name`, `age`) VALUES ('5', 'dog', '42'); 
  目标:我们要去掉name相同的数据。
  先看看哪些数据重复了:
  SELECT name,count( 1 )   
  FROM  
   student   
  GROUP BY  
  NAME   
  HAVING  
   count( 1 ) > 1; 
  输出:
  name count(1) cat 2 dog 2 
  name为cat和dog的数据重复了,每个重复的数据有两条;
  Select * From 表 Where 重复字段 In (Select 重复字段 From 表 Group By 重复字段 Having Count(1)>1) 
  删除全部重复数据,一条不留
  直接删除会报错:
  DELETE   
  FROM  
   student   
  WHERE  
   NAME IN (  
   SELECT NAME   
   FROM  
    student   
   GROUP BY  
   NAME   
  HAVING  
   count( 1 ) > 1) 
  报错:
  1093 - You can't specify target table 'student' for update in FROM clause, Time: 0.016000s 
  原因是:更新这个表的同时又查询了这个表,查询这个表的同时又去更新了这个表,可以理解为死锁。mysql不支持这种更新查询同一张表的操作。
  解决办法:把要更新的几列数据查询出来做为一个第三方表,然后筛选更新。
  DELETE   
  FROM  
   student   
  WHERE  
   NAME IN (  
   SELECT  
    t.NAME   
  FROM  
   ( SELECT NAME FROM student GROUP BY NAME HAVING count( 1 ) > 1 ) t) 
  删除表中删除重复数据,仅保留一条
  在删除之前,我们可以先查一下,我们要删除的重复数据是啥样的。
  SELECT  
   *   
  FROM  
   student   
  WHERE  
   id NOT IN (  
   SELECT  
    t.id   
   FROM  
   ( SELECT MIN( id ) AS id FROM student GROUP BY `name` ) t   
   ) 
  啥意思呢,就是先通过name分组,查出id最小的数据,这些数据就是我们要留下的火种,那么再查询出id不在这里面的,就是我们要删除的重复数据。
  开始删除重复数据,仅留一条
  很简单,刚才的select换成delete即可。
  DELETE   
  FROM  
   student   
  WHERE  
   id NOT IN (  
   SELECT  
    t.id   
   FROM  
   ( SELECT MIN( id ) AS id FROM student GROUP BY `name` ) t   
   ) 
  90万+的表执行起来超级快。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号