【问题标题】:Deleting duplicates from a large table从大表中删除重复项
【发布时间】:2011-01-24 01:30:05
【问题描述】:

我有一个包含 19 000 000 条记录的相当大的表,但我遇到了重复行的问题。即使在 SO 中也有很多类似的问题,但似乎没有一个能给我一个满意的答案。需要考虑的几点:

  • 行唯一性由两列确定,location_iddatetime
  • 我希望尽可能缩短执行时间(
  • 复制表格不太可行,因为表格有几 GB 大小。
  • 无需担心关系。

如前所述,每个location_id 只能有一个不同的datetime,我想删除所有重复的实例。哪一个幸存下来并不重要,因为数据是相同的。

有什么想法吗?

【问题讨论】:

  • 考虑删除临时索引,如果存在则触发。
  • stackoverflow.com/questions/1585412/… 中给出的方法有什么问题?
  • @Pentium10,很好,可以加快速度,但如果我使用子查询解决方案,也会降低性能。
  • 当您有索引时,先尝试生成删除 SQL id,而不发出删除。删除索引后,运行更长的纯文本 SQL,其中包含一堆 ID

标签: mysql unique duplicates


【解决方案1】:

我认为您可以使用此查询从表中删除重复记录

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime)

在此之前,只需先用一些样本数据进行测试..然后试试这个....

注意:在 5.5 版上,它适用于 MyISAM,但不适用于 InnoDB。

【讨论】:

  • 这看起来很有希望,我以前没有听说过这个功能。现在试试,我会让你知道结果如何。欢迎来到 SO :)
  • 这行得通,谢谢。花了 31 分钟完成 16 982 040 行和 1 589 908 次重复。我不敢相信它会这么简单,没有额外的表或复杂的查询。 :)
  • @Vinodkumar Saravana,我正在使用 InnoDB 运行 5.5,我阅读了您的说明,但为了确定,我还是尝试了它。 (当然它不起作用),但你能解释一下为什么它在 InnoDB 上不起作用吗?
  • @tixastronauta - 似乎 InnoDB 版本的 Mysql 存在一些错误。不过,您可以将表从 InnoDB 转换为 MyIsam,然后应用 alter ignore 查询。然后再次转换为 InnoDB。但在转换之前进行备份。或者您可以使用 set session old_alter_table=1;参考:dev.mysql.com/doc/refman/5.1/en/server-options.html
  • 'Alter Ignore table' 不适用于 mysql 5.7 以上。也许它不适用于 InnoDB 表。您可以先将表转换为 MyISAM,然后删除重复项并将其返回到 InnoDB,使用:stackoverflow.com/a/23421788
【解决方案2】:
SELECT *, COUNT(*) AS Count
FROM table
GROUP BY location_id, datetime
HAVING Count > 2

【讨论】:

    【解决方案3】:
    UPDATE table SET datetime  = null 
    WHERE location_id IN (
    SELECT location_id 
    FROM table as tableBis
    WHERE tableBis.location_id = table.location_id
    AND table.datetime > tableBis.datetime)
    
    SELECT * INTO tableCopyWithNoDuplicate FROM table WHERE datetime is not null
    
    DROp TABLE table 
    
    RENAME tableCopyWithNoDuplicate to table
    

    因此,您保留日期时间较短的行。我不确定性能,这取决于您的表格列、您的服务器等...

    【讨论】:

      【解决方案4】:

      此查询适用于所有情况:针对 Engine : MyIsam 测试了 200 万行。

      ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime)

      【讨论】:

        【解决方案5】:

        您可以使用以下步骤删除重复项: 1- 将以下查询的结果导出到 txt 文件中:

        select dup_col from table1 group by dup_col having count(dup_col) > 1
        

        2- 将其添加到上述 txt 文件的第一个并运行最终查询:

        delete from table1 where dup_col in (.....)
        

        请注意,'...'是第一步创建的txt文件的内容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-09-19
          • 1970-01-01
          • 1970-01-01
          • 2014-09-30
          • 2021-04-02
          • 2016-01-28
          相关资源
          最近更新 更多