MySQL:删除分区与从中删除

MySQL: DROP PARTITION vs DELETE FROM

对于MySQL;

DROP PARTITIONDELETE WHERE 查询有何区别? 什么时候使用哪个?

我的场景:

很简单,就是在每个月底从我的几个表中删除一个月前的数据。表格以每秒大约 5 个条目的缓慢速度填充。

优点/缺点

PARTITION使用 InnoDB 需要我禁用我的 FOREIGN KEYs。所以,DELETEing 对我来说似乎更好。 PARTITIONing 能给我带来什么好处?难道只是查询的执行速度,a.k.a。表现?我的删除查询 运行 每个月只会执行一次,所以我没有发现执行时间有问题。

就其价值而言,删除分区是一种数据定义语言语句。它发生得很快。

DELETE 是一个数据操作语句。如果您使用 InnoDB(您可能会这样做),它就是事务性的。这是什么意思?

当您发出声明时,例如,

DELETE FROM tbl WHERE start_date < CURDATE() - INTERVAL 1 MONTH

这意味着访问您的数据库的其他程序将在您的 DELETE 事务之前看到您正在删除的所有行,或者其中的 none。该操作称为 atomic or indivisible -- 它似乎是同时发生的。

如果您删除很多行,这会给您的数据库服务器带来很大的负担。它必须累积包含所有已删除行的事务日志,然后一次提交所有事务日志,可能会锁定其他访问。

你的问题说你每个月必须删除大约 13 个 megarows。如果仅使用一个 DELETE 语句来执行此操作,则会给数据库带来沉重的负担。为了减少删除不需要的历史行时的负担,请分块执行 DELETE 操作。如何?你有几个选择。

  • @Akina 建议:经常删除,不要一次删除大量行,或者

  • 批量删除1000行,语句如下:

      DELETE FROM tbl 
       WHERE start_date < CURDATE() - INTERVAL 1 MONTH
       LIMIT 1000;
    

    并重复该语句,直到它不删除任何行。

“每秒 5 个条目”= 大约 400K/天或 13M/月

DELETING 3M 行 在单个语句中:

  • 那么多行非常慢。 (对于 1K 行以下来说还不错)
  • 在 table
  • 上阻止最多 activity
  • 为潜在的“回滚”(在断电的情况下)建立一个非常大的清单

预定删除

  • 为什么要等月底?每分钟最多做1000次;这将跟上更少的开销。 一定要有一个suitable索引,否则效率不高
  • 与其按月执行任务,不如设置一个持续 运行ning 的单独任务,最多删除 200 行,然后继续执行下一个 table;最终重复。 (如果跟不上,增加“LIMIT 200”;如果侵入性太大,在循环中添加一个 SLEEP。)
  • 不要使用 cron 或 EVENT 来安排删除。如果出于某种原因,删除 运行 未能在下一次删除之前完成,则该作业可能会变成火车残骸。 OTOH,continually-running 工作需要一个“keep-alive”任务来重新启动它,如果它因任何不可预见的原因而死亡。

DROP PARTITION

  • 由于 PARTITIONs 作为单独的 'tables' 实现的方式,DROP PARTITION 类似于 DROP TABLE
  • 非常快,无论分区中的行数如何。 (好吧,OS 对于大文件可能会表现出轻微的迟缓。)
  • 如果使用 PARTITION BY RANGE(..) 就很容易做到。
  • 我建议分区数在20到50之间;相应地调整删除频率。 (1 个月保留 --> 每日分区;3 个月保留 --> 每周分区;1 年保留 --> 每月或每周;等等)
  • 分区时 table,重新考虑所有索引。您可能 能够通过使用分区 p运行ing 改进一些查询。 (但不要期望太多。)
  • 更多信息:Partition
  • PARTITIONingFOREIGN KEYS 和一些 UNIQUE 键冲突。这给程序员带来了负担,担心(或忽略)这些约束的丢失。

这是我关于其他 big deletions 技术的博客