【问题标题】:Approximately how long should it take to delete 10m records from an MySQL InnoDB table with 30m records?从具有 30m 条记录的 MySQL InnoDB 表中删除 10m 条记录大约需要多长时间?
【发布时间】:2011-03-11 17:24:02
【问题描述】:

我正在使用查询删除表中大约 1/3 的记录:

DELETE FROM `abc` LIMIT 10680000;

查询出现在进程列表中,状态为“正在更新”。总共有 30m 条记录。该表有 5 列和两个索引,当转储到 SQL 时,文件大约 9GB。

这是 MySQL 中唯一的数据库和表。

这是在具有 2GB 内存、3 GHz 四核处理器和快速 SAS 磁盘的机器上运行的。 MySQL 不执行除此 DELETE 操作之外的任何读取或写入操作。机器上没有其他“繁重”进程正在运行。

此查询已运行超过 2 小时 -- 我预计需要多长时间?

感谢您的帮助!我对 MySQL 还是很陌生,所以任何关于运行此查询时“幕后”发生的事情的花絮都非常感谢。

如果我能提供任何其他相关信息,请告诉我。

更新:我刚刚运行了一个COUNT(*),在 2 小时内,它只删除了 20 万条记录。我想我会采纳 Joe Enos 的建议,看看将数据插入新表并删除前一个表的效果如何。

更新 2: 抱歉,我实际上误读了号码。在 2 小时内,它没有被删除任何内容。我糊涂了。有什么建议吗?

更新 3: 我最终将 mysqldump--where "true LIMIT 10680000,31622302" 一起使用,然后将数据导入到新表中。然后我删除了旧表并重命名了新表。这花了半个多小时。

【问题讨论】:

  • 你知道没有 ORDER BY 的 LIMIT 意味着它可以选择任意 1000 万条记录进行删除吗?
  • 哦,谢谢你的提示。我只是想删除 1/3 的记录,所以没关系。会不会是和我只是查询SELECT * FROM abc LIMIT 10680000; 一样的记录集?该查询始终返回相同的记录集。表格有“自然顺序”吗?
  • 被删除的桌子上的PK是否有任何FK?这些可能会降低删除性能,因为数据库必须检查以确保在删除过程中没有违反这些。
  • btreat:不,没有。数据库中没有任何其他表——只有一张。不过感谢您的提示,我会记住这一点的。
  • 不,表格没有定义的自然顺序。当然,数据在磁盘上确实有一些顺序,这就是为什么您始终获得相同记录的原因。不过,只要数据库喜欢它,这个顺序可能会改变,因此不能依赖它。

标签: mysql


【解决方案1】:

不知道这是否会更好,但可能值得考虑执行以下操作: 创建一个新表并将原表的 2/3 插入到新表中。 删除原始表。 将新表重命名为原始表的名称。

这会阻止日志文件有所有的删除,但我不知道插入 20m 记录是否比删除 10m 更快。

【讨论】:

  • 好点——这可能会快很多!整个数据库在不到 30 分钟的时间内从 SQL 文件中插入。将数据转储到LIMIT 10680000,31622302 的最佳方法是什么?
  • 我不是 MySql 人,但如果 MySql 和其他 DB 提供程序一样,那么应该有一个 SELECT INTO 语法,您可以在其中选择要保留的记录,它会自动插入,而不是转储和单独的插入。假设这存在,那么您可以编写一个您想要的 SELECT 语句,在查询中使用“INTO NEW_TABLE_NAME”,然后它会完成其余的工作。
【解决方案2】:

您应该发布表格定义。 另外,要知道为什么要花很多时间,请尝试通过以下方式在删除请求上启用配置文件模式:

SET profiling=1; 
DELETE FROM abc LIMIT 10680000;
SET profiling=0;
SHOW PROFILES;
SHOW PROFILE ALL FOR QUERY X; (X is the ID of your query shown in SHOW PROFILES)

并发布它返回的内容(但我认为查询必须结束才能返回分析数据)

http://dev.mysql.com/doc/refman/5.0/en/show-profiles.html

另外,我认为您会在 ServerFault 上收到更多回复;)

【讨论】:

    【解决方案3】:

    当您运行此查询时,数据库的 InnoDB 日志文件用于记录已删除行的所有详细信息 - 如果此日志文件从一开始就不够大,它将自动扩展必要时(如果配置为这样做) - 我不熟悉具体细节,但我希望这种自动扩展不会快得令人眼花缭乱。 2 小时确实看起来很长 - 但如果日志文件随着查询的运行而增长,我并不感到惊讶。

    要删除记录的表是否位于外键末尾(即另一个表是否通过 FK 约束引用它)?

    【讨论】:

    • 不,数据库中没有其他表——只有一张。
    • 如果另一个表通过 FK 约束引用它,情况会如何变化?
    【解决方案4】:

    我希望您的查询现在结束... :) 但据我所见,LIMIT 大数字(我从未尝试过这种数字)非常慢。我会尝试一些基于 pk 之类的东西

    DELETE FROM abc WHERE abc_pk < 10680000;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2013-05-02
      • 2019-01-28
      • 2023-02-25
      • 2013-05-08
      • 1970-01-01
      相关资源
      最近更新 更多