Mysql 删除超大数据库中的重复条目

Mysql 删除超大数据库中的重复条目,mysql,Mysql,上周我无意中在我们的网站上引入了一个bug,它在接收要插入数据库的数据时不断报告错误,尽管它正确地添加了新条目。因此,信息不断发送,并不断报告在数据库上写入和写入时出现错误,每个条目都会重复几十到几百次。我不知道为什么循环停止了,但它最终给出了一个OK,并停止了写入 起初我不明白这个错误来自我的代码,所以我花了几天时间才解决它,与此同时,我们的数据库不断遭到轰炸和淹没 事后看来,我并没有很好地处理这件事,我知道,但我想纠正我所犯的错误 我一直在堆栈中搜索清除重复行的方法,有几十个问题和答案,所以

上周我无意中在我们的网站上引入了一个bug,它在接收要插入数据库的数据时不断报告错误,尽管它正确地添加了新条目。因此,信息不断发送,并不断报告在数据库上写入和写入时出现错误,每个条目都会重复几十到几百次。我不知道为什么循环停止了,但它最终给出了一个OK,并停止了写入

起初我不明白这个错误来自我的代码,所以我花了几天时间才解决它,与此同时,我们的数据库不断遭到轰炸和淹没

事后看来,我并没有很好地处理这件事,我知道,但我想纠正我所犯的错误

我一直在堆栈中搜索清除重复行的方法,有几十个问题和答案,所以我提出了一个似乎有效的解决方案

DELETE FROM app_info
WHERE  `idinfo` NOT IN (SELECT minid
                        FROM   (SELECT Min(`idinfo`) AS minid
                                FROM   app_info
                                GROUP  BY `when`,
                                          `idbooth`,
                                          `iddongle`,
                                          `typeinfo`,
                                          `money`,
                                          `money2`,
                                          `currency`,
                                          `stock`,
                                          `i1`,
                                          `i2`,
                                          `i3`,
                                          `i4`,
                                          `i5`,
                                          `str1`,
                                          `str2`,
                                          `pbnew`,
                                          `in1`,
                                          `in2`,
                                          `in3`,
                                          `in4`,
                                          `in5`,
                                          `in6`,
                                          `in7`,
                                          `in8`) e)
       AND `idinfo` < 1545000
       AND `idinfo` > 1541500;
但是,我还无法将第一个查询重新格式化,以考虑到第二个查询生成的信息。起初,我认为用我在第二个查询中分组的字段上的信息替换我用来制作方括号的WHEN会有所帮助,但如果我这样做,我会得到0行,因此它不会起任何作用

还取决于所选的条目,如果它有太多的副本,就像有数百个副本的副本一样,它会使数据库崩溃。。。所以这似乎不是我想要的解决方案


我不知道该试什么了。当重复条目的数量如此之多时,我如何才能在不破坏数据库的情况下清除它们?我想占用数据库是不可避免的,但是我可以发布一个停机时间来进行维护,所以这不会是一个问题。

我建议使用一个临时表来存储重复的ID

使用select查询,该查询提供要删除的重复ID,但将记录插入到新表中。对于group by,这可能需要一段时间,但不会锁定数据库

运行任何需要的测试,以验证临时表只包含需要删除的ID

在一个维护窗口中,备份后,在select ID from temp_表中运行delete where ID

如果这仍然太长,可以从temp表中批量执行


主要的优点是,在锁定表以进行删除的同时,您没有在表上运行大而重的查询,这甚至可能导致死锁。

有效地,您可以使用INSERT IGNORE查询。步骤如下:

创建一个临时表,该表与现有表的架构类似 桌子

向所需的列添加唯一约束

运行INSERT IGNORE将数据从原始表复制到临时表。这样,任何重复的行都不会插入到临时表中,因为它们违反了已被忽略的唯一约束

将原始表重命名为其他名称,并重命名临时表 将表添加到原始表

删除冗余表。
希望这能有所帮助。

感谢您对其进行格式化。我认为您在子查询中缺少COUNT*>1,很抱歉您花了这么长时间才接受答案。上周我很忙。这是对我帮助最大的,谢谢!我可以在大约一个小时内完成,必须分几批完成,但数量不如我之前做的那么多。再次感谢。
SELECT *  FROM  `App_info`  
WHERE  `when` >  '2018-11-05' 
GROUP BY  `typeInfo` ,  `str2`  
ORDER BY  `App_info`.`when` ASC