【问题标题】:Very slow MySQL delete非常慢的 MySQL 删除
【发布时间】:2019-06-19 13:37:39
【问题描述】:

所以我试图从一个相当大的 mysql(innodb) 表中删除一些行。

我尝试使用的查询如下:

delete from item where id in (select id from items_to_be_deleted);

item 是一个 70'000'000 行的表,items_to_be_deleted 是一个 1'000'000 行的表。

我的查询似乎永远不会完成,即使我添加了一个非常小的限制。 (delete from item where id in (select id from items_to_be_deleted) LIMIT 10;

如果我运行select id from items_to_be_deleted,它几乎会立即返回,它只是一个带有主键 (id) 和另一个 varchar 字段的表。

我的查询有什么问题需要这么长时间/似乎永远不会完成?

【问题讨论】:

标签: mysql innodb


【解决方案1】:

IN 子句作为 OR 子句的迭代,因此您可以使用基于与 IN 子句相同的子查询的内连接来避免这种情况

delete item
from item
inner join  (
  select id 
  from items_to_be_deleted
) t on t.id  = item.id 

【讨论】:

    【解决方案2】:

    JOIN怎么样?

    DELETE i
    FROM Item i
    INNER JOIN items_to_be_deleted i2 ON i.ID = i2.ID
    

    【讨论】:

      【解决方案3】:

      其他方式可以是使用 EXISTS 操作符和依赖子查询:

      DELETE i FROM item i 
      WHERE EXISTS (
         SELECT 1 FROM items_to_be_deleted WHERE id = i.id
      )
      

      【讨论】:

      • 很确定这个相关的子查询会以某种方式出错。因为id 不是完全限定或别名,并且两个表中都存在 id 列。我很想写DELETE FROM item WHERE EXISTS ( SELECT 1 FROM items_to_be_deleted WHERE items_to_be_deleted.id = item.id )并使用完全合格的
      • 我总是这样使用它。 unaliased id 与正确的内部表相关,因为外部表的优先级低于内部子查询的优先级。另外,我从不使用表名作为别名,最好为 ..._deleted 添加一个别名,imo。
      • “我总是这样使用它。无别名的 id 与正确的内部表相关,因为外部表的优先级低于内部表” 相信优化器会这样做是很棘手的,因为您的查询不是work
      • 我修复了delete i from db-fiddle.com/f/7ZdDtUAM3tqML5BQUxVdNH/0 的查询,谢谢。
      • “忘记这一点,谢谢。” 没问题,但确实 +1 愚弄了要从“多个表”中删除的优化器,因为 DELETE <columns> FROM ... 是多个表删除语法,奇怪的是,当您使用所需的别名时,我也不知道这一点,因为我几乎不使用任何相关的子查询,请考虑 this
      【解决方案4】:

      删除一百万行时,请分块执行。否则,undo log 的构建将是一个杀手锏。它必须保存所有以前的百万行,然后再真正折腾它们。

      由于它只是表的一小部分,我不建议将要保留的行复制到新表中。

      快速制作DELETE 的多种方法:http://localhost/rjweb/mysql/doc.php/deletebig

      要尝试实现的一件事,因为每折腾 1 需要保留 69 行:尝试让 1M 行的表驱动查询。大多数解决方案涉及扫描所有 70M 行,并根据较小的表检查每一行。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-23
        • 1970-01-01
        • 2021-05-29
        • 1970-01-01
        • 2014-07-16
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多