【问题标题】:How to make delete duplicates faster?如何更快地删除重复项?
【发布时间】:2019-06-07 18:41:45
【问题描述】:

在大约 170 万行的表上,我尝试删除重复的帖子:

delete a FROM comment a
  INNER JOIN comment a2
     WHERE a.id < a2.id
     AND   a.body = a2.body;

结果是:

  Query OK, 35071 rows affected (5 hours 36 min 48.79 sec)

这发生在我几乎空闲的工作站上,Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz。 我想知道是否有一些技巧可以让这个删除操作更快?

【问题讨论】:

  • 一次性删除它们不是一个好主意,尝试使用过滤子句进行增量删除,例如:使用filer中的日期列
  • 您的表格评论中有多少行? .. 你在 db 上只留下最后一条评论名称重复?
  • @Ven,请用示例查询详细说明。
  • @scaisEdge,正如我所说,大约有 170 万行。
  • @Milkyway 如果您有一列可以用于删除记录的表,我已经通过这种方式在生产中解决了这个问题。因为这不会导致日志文件增长问题,例如:delete a from comment a inner join comment a2 on a.body = a2.body and a.datecolumn between '2018-01-06' and '2019-01-06'

标签: mysql sql sql-delete


【解决方案1】:

下面的查询将对您有用。

Delete  YourTableName 
From    (
Select  row_number() over(Partition by ColName1,ColName2,ColName3 order by ColName1,ColName2,ColName3 Asc)As RowNumber
        )YourTableName
Where   YourTableName.RowNumber>1

如果它正在工作,请标记为答案

【讨论】:

    【解决方案2】:

    对于 MySQL,您可以尝试(假设行具有完全相同的列信息):

    ALTER IGNORE TABLE comment ADD UNIQUE INDEX idx_name (id, body);
    

    Source

    【讨论】:

    • 不确定如何在我的特定用例中实现它。
    • 这不适用于 mysql。我得到#1327 - Undeclared variable: NewTable,尽管我已经创建了它:CREATE TABLE NewTable` LIKE comment;`mysql 上的重命名命令应该是RENAME TABLE NewTable` TO comment;`
    • 本答案与题主要求无关。
    • 在 170 万行的表上添加索引的性能如何,执行需要多长时间?
    【解决方案3】:

    您的查询正在尝试对同一行进行无数次删除。例如,如果您有以下数据:

    body   id
      a     1
      a     2
      a     3
      a     4
    

    然后您的查询尝试进行以下删除:

     c.body   c.id  c2.id
      a         1      4
      a         1      3
      a         1      2
      a         2      4
      a         2      3
      a         3      4
    

    随着给定bodyids 的数量增加,您可以看到这将如何为数据库带来大量工作。

    您可以改用group by 来解决此问题:

    delete c 
        from comment c join
             (select c2.body, max(c2.id) as max_id
              from comment c2
              group by c2.body
             ) c2
             on c2.body = c.body and c.id < c2.max_id;
    

    此外,您还需要comment(body, id) 上的索引。

    您可能还会发现反连接比您尝试的连接效果更好:

    delete c 
        from comment c left join
             comment c2
             on c2.body = c.body and c2.id > c.id
        where c2.id is null;
    

    【讨论】:

    • 这也好不到哪里去。我在同一台机器上有 370K 行的表上尝试过,结果如下:Query OK, 27875 rows affected (10 hours 57 min 26.10 sec)
    • @Milkyway 。 . .您是否创建了答案推荐的索引?
    • 不,我没有。我会在另一张桌子上尝试并提供反馈。谢谢。
    猜你喜欢
    • 2019-12-13
    • 2010-11-11
    • 1970-01-01
    • 2017-12-25
    • 2019-09-26
    • 1970-01-01
    • 2018-02-17
    • 2022-12-18
    • 2023-02-03
    相关资源
    最近更新 更多