【问题标题】:What is the fastest way to delete millions of rows from a MySQL database?从 MySQL 数据库中删除数百万行的最快方法是什么?
【发布时间】:2019-07-12 04:29:59
【问题描述】:

我的数据库空间不足,所以我对旧记录进行了备份。现在我要清除这些记录,我的参考列是'日期'。

我尝试使用标准方法:

DELETE FROM table WHERE date >= '2017-01-01' AND date <= '2017-12-31'

但这显然花费了太多时间,因为要删除的行数超过 700 万行。有没有办法加快这个速度?我试图分成几个月甚至更小的块,但在运行代码一段时间后,我与服务器断开连接。

提前致谢。

编辑:

CREATE TABLE table (

  id INT(11) NOT NULL AUTO_INCREMENT,
  date DATE DEFAULT NULL,
  # 18 more columns

  PRIMARY KEY (id)
)
ENGINE = INNODB,
AUTO_INCREMENT = 29616055,
AVG_ROW_LENGTH = 317,
CHARACTER SET utf8mb4,
COLLATE utf8mb4_general_ci;

【问题讨论】:

  • 您尝试过什么调试问题?有没有设置索引?
  • 表的引擎是 InnoDB 还是 MyISAM? (或者要回答我和 Nico 的问题,请将表格的 CREATE 语句添加到您的问题中)。
  • 可能是您的日期字段未编入索引。
  • MySqlSql 标记
  • ALTER TABLE `table` ADD INDEX date_index (`date`); 你的专栏date 是什么类型的?

标签: mysql sql


【解决方案1】:

如果你有足够的空间,那么创建一个临时表并重新加载原表:

create table temp_t as
    select *
    from table
    where date >= '2018-01-01';

truncate table t;

insert into t
     select *
     from temp_t;

这节省了delete 的所有日志记录开销——这可能非常昂贵。

接下来,您需要了解分区。这使得该过程更加简单。您可以只删除一个分区,而不是删除行 - 并且没有用于删除分区的逐行日志记录。

【讨论】:

  • 太棒了。它就像魅力一样。我已经在大约 11 亿行上测试了这个答案,它按预期工作。感谢您分享这个答案。
  • 这是一个很好的删除替代方案,我想知道create table如何更快。
  • @joel 。 . .更少的日志记录和最小的锁定影响。
【解决方案2】:
  1. 创建表的空副本(键和所有)。
  2. INSERT...从原始数据中选择要保留到副本中的数据。
  3. 删除所有引用原始表的外键约束。
  4. 删除原始表。
  5. 将副本重命名为原始名称。
  6. 重新创建在步骤 3 中删除的所有外键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 2010-11-22
    • 1970-01-01
    • 2019-02-15
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    相关资源
    最近更新 更多