批量数据删除的方法

【 TiDB 使用环境】生产环境 or 测试环境 or POC
【 TiDB 版本】
关于批量数据删除,看到有如下一段介绍:

在删除大量数据的时候,建议使用 Delete * from t where xx limit 5000; 这样的方案,通过循环来删除,用 Affected Rows == 0 作为循环结束条件。

如果一次删除的数据量非常大,这种循环的方式会越来越慢,因为每次删除都是从前向后遍历,前面的删除之后,短时间内会残留不少删除标记(后续会被 GC 清理掉),影响后面的 Delete 语句。如果有可能,建议把 Where 条件细化。举个例子,假设要删除 2017-05-26 当天的所有数据,那么可以这样做:

for i from 0 to 23 :

while affected_rows > 0 :

delete * from t where insert_time >= i: 00 : 00 and insert_time < ( i +1) : 00 : 00 limit 5000; ``

affected_rows = select affected_rows ()

上面是一段伪代码,意思就是要把大块的数据拆成小块删除,以避免删除过程中前面的 Delete 语句影响后面的 Delete 语句。

问题:
为什么要采取这种方式进行呢?有什么考虑吗?

【遇到的问题】
【复现路径】做过哪些操作出现的问题
【问题现象及影响】

【附件】

请提供各个组件的 version 信息,如 cdc/tikv,可通过执行 cdc version/tikv-server --version 获取。

3 个赞

这里我觉得解释的挺清楚了,还有哪里有疑惑吗。

1 个赞

你需要这篇文章:eyes:

2 个赞

我经常是这么干的,主键是数字类型的,找最大和最小,然后写脚本,在最小值上+偏移量,带上where条件,然后逐步递增,每个批次执行,直到最大值,有删空的,但是是主键扫描,比较快。
全部都删就只能truncate

1 个赞

我不清楚,为啥说采用循环方式,后面的删除动作会越来越慢,如果说是因为删除的数据不会真正的删除,后面的删除操作仍然会scan之前已经删除过的数据,那我感觉采用1小时一批次去删除和采用1天一批次去删除,是遍历区间的差别吗?

1 个赞

我是这样理解的。采用1小时一批次去删除相对1天一批次去删除每次循环的区间更小了,整体速度肯定更快。比如要删100w条数据,这100w条按小时均匀分布在1天里。如果按天limit5000去删,由于只是标记而不是真正删除,每批次需要遍历的数据会越来越多,删到最后一批次大概需要遍历100w条。按小时删,每小时一批次limit5000去删,每批删到最后一次大概需要遍历100w/24条。

1 个赞

OK,

1 个赞

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。