删除剩余的行 MySql

Delete the remaining rows MySql

  1. 假设有一个 table 有 1M 行,类别为 1-100。
  2. 我需要更新 f.e 所在的行。 category=10(假设有 150k 行)。
  3. 我将更新 120k 行,需要删除 30k 行。

第一个想法: 目前我正在使用开始将所有行更新为 0,并在更新时将此值更改为 1。然后删除类别 = 10 和更新 = 0 的所有行。

将 150k 行更新为 0(其中类别 = 10)时存在性能问题。有时需要 30 秒,因为可能有 20 万行,而不仅仅是 3 万行。

第二个想法 一开始,循环所有 150k 行以将 id 保留在数组中,然后用更新的 id 填充一个新数组,最后使用 array_diff 删除剩余的 id。

sql 也存在性能问题,比如“... where id in (...30k ids...)”。

你们有没有用更好的东西来解决这个问题? 谢谢

您第一个想法的变体:将您的标志列定义为时间戳而不是布尔值,这样您就不必花 30 秒将其初始化为 0。只需在更新行时将该时间戳更新为 NOW()。完成后,应删除标志列早于第一个更新行的任何行。我假设这个 update/delete 任务会定期再次完成,但只要任务不重叠,时间戳应该仍然有效。

第二个想法的变体:不要运行查询DELETE FROM imagine WHERE id IN(...30k ids...)谓词。相反,您可以 运行 一系列 DELETE FROM imagine WHERE id IN (...100 ids...)。遍历您的 ID 列表并一次删除 100 个批次。这样你需要 运行 300 条 DELETE 语句,但很容易编写循环。

解决方案1之二,如果你追求的是性能

动态添加默认值为 0 的新字段比更新现有字段的 30K 行要快。

最后你可以删除这个字段,这也是一个快捷命令。

大型更新(或删除)代价高昂,因为在发生崩溃时需要保存旧行。

如果这是一次性任务并且你不需要担心在更新期间阻塞其他activity,然后简单地做查询,然后让如有必要,他们会花几分钟时间。

如有其他限制,请说明。并请提供 SHOW CREATE TABLE,加上建议的更新和删除语句。

对于某些情况,最好使用 PRIMARY KEY 遍历 table。一次做 1000 行。也就是说,首先找到跨越该范围的 id 范围,然后执行每个更新和删除,但限制(通过 WHERE)范围。 (在某些情况下,他们可能不会修改任何行,但这没关系。)每个块之后 COMMIT

更多详情:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks