11亿表的数据删除数据越删越慢

【 TiDB 使用环境】生产环境

表里11亿的数据,通过以下sql删了6亿左右的时候,一个删除语句就非常慢了,执行得3s多,最开始是0.5s就能执行完,论坛搜了下,好像没有什么解决方案,也没有修改过gc的时间,个人感觉像是之前删除的数据没有被gc掉,导致现在的删除都得扫描非常多的数据

执行sql

 EXPLAIN analyze DELETE from h_equip_bin_box_status_history  where gmt_create < '2023-07-01 00:00:00'  limit 10000

执行计划

Delete_5	N/A	0	root		time:3.44s, loops:1	N/A	172.7 KB	N/A
└─Limit_9	10000.00	10000	root		time:3.34s, loops:11	offset:0, count:10000	N/A	N/A
  └─TableReader_14	10000.00	10000	root		time:3.34s, loops:10, cop_task: {num: 645, max: 654.6ms, min: 440.1µs, avg: 300.1ms, p95: 505.5ms, max_proc_keys: 992, p95_proc_keys: 224, tot_proc: 3m12.2s, tot_wait: 621ms, rpc_num: 645, rpc_time: 3m13.6s, copr_cache_hit_ratio: 0.09, distsql_concurrency: 60}	data:Limit_13	3.15 MB	N/A
    └─Limit_13	10000.00	10208	cop[tikv]		tikv_task:{proc max:767ms, min:1ms, avg: 327ms, p80:392ms, p95:504ms, iters:720, tasks:645}, scan_detail: {total_process_keys: 10208, total_process_keys_size: 1321747, total_keys: 715402150, get_snapshot_time: 51.6ms, rocksdb: {delete_skipped_count: 1204377, key_skipped_count: 716605941, block: {cache_hit_count: 1022827, read_count: 924, read_byte: 55.0 MB, read_time: 36.8ms}}}	offset:0, count:10000	N/A	N/A
      └─Selection_12	10000.00	10208	cop[tikv]		tikv_task:{proc max:767ms, min:1ms, avg: 327ms, p80:392ms, p95:504ms, iters:720, tasks:645}	lt(lyzhhw4.h_equip_bin_box_status_history.gmt_create, 2023-07-01 00:00:00.000000)	N/A	N/A
        └─TableFullScan_11	12383.59	10208	cop[tikv]	table:h_equip_bin_box_status_history	tikv_task:{proc max:767ms, min:0s, avg: 327ms, p80:392ms, p95:504ms, iters:720, tasks:645}	keep order:false	N/A	N/A

建议参考一下这篇文章

GC不是物理删除,只是再rocksdb打标,等着rocksdb compact时才真正删除这些数据
6.5.1 用非事务DML吧 batch delete
https://docs.pingcap.com/zh/tidb/stable/non-transactional-dml#非事务-dml-语句

2 个赞

rocksdb compact的时间节点是怎么样的 有相关的文档说明么

相关参数的文档

https://docs.pingcap.com/zh/tidb/stable/tikv-configuration-file#region-compact-check-interval

可以先看下这个

1 个赞

看一下这个

这个语句都没有走索引么?

之前是说这个数值是删除的副本吧

这是tidb的特性,delete越删除越慢,而且删除后regions是不释放的,最好用分区表然后drop分区删除数据

官网文档,写得是越删除越慢 TiDB 最佳实践 | PingCAP 文档中心

1 个赞

有索引但是走不上索引 我analyze table了也没用
如果FORCE INDEX(idx_gmt_create)强行指定索引的话效果是一样的,同样也得这么久

时间条件改成gmt_create < ‘2023-07-01 00:00:00’ and gmt_create > '2023-06-30 00:00:00’这种,可以参考我上面转发的文章,自动生成删除脚本

越来越慢,我能说是常见的不哈。

我想问一下,都删掉2023年7月1号了,为什么不是建个新表,而是大量的删数据,删完之后不会有大量的碎片吗?

1 个赞

delete大量数据是tidb的功能痛点啊

:sweat_smile:额。。。突然发现了一条捷径~

研究了今天,发现delete删除不会释放已经占用的regions数量,也不会减少regions大小,也释放不了占用的硬盘。
删除过程会有大量的数据写入,结果越删磁盘占用越多。。

因为他删除的底层原理只是追加数据进行打标…要等他compact才会真的释放空间
但是compact得时机有点没看懂,我删完都已经好几天了regin都没较少

1 个赞

因为7月1号后也有3亿多数据 就算建个新表插数据也不一定好操作…之前试了下insert into…select 发现完全跑不动

这么大的表分区了么,梅分区肯定慢,分区能加快数据delete速度

tikv挨个低峰时 手工compact一下