表大批量删除数据后 使用不带任何条件的limit1非常慢

背景为一张13亿左右数据的表,通过非事务dml删除了10亿条左右数据,剩余了2亿条左右的数据

现在执行 select * from xxx limit 1 需要3分钟多才能出结果
如果在where条件里使用索引查询是正常的

执行计划:

Limit_7	1.00	1	root		time:3m24.4s, loops:2	offset:0, count:1	N/A	N/A
└─IndexReader_14	1.00	1	root		time:3m24.4s, loops:1, cop_task: {num: 1829, max: 402.8ms, min: 134.9µs, avg: 111.7ms, p95: 246.4ms, max_proc_keys: 1, p95_proc_keys: 0, tot_proc: 3m22.7s, tot_wait: 42ms, rpc_num: 1829, rpc_time: 3m24.3s, copr_cache_hit_ratio: 0.46, distsql_concurrency: 1}	index:Limit_13	326 Bytes	N/A
  └─Limit_13	1.00	1	cop[tikv]		tikv_task:{proc max:472ms, min:33ms, avg: 186.8ms, p80:229ms, p95:280ms, iters:1829, tasks:1829}, scan_detail: {total_process_keys: 1, total_process_keys_size: 46, total_keys: 851728674, get_snapshot_time: 283.7ms, rocksdb: {delete_skipped_count: 19440216, key_skipped_count: 871167911, block: {cache_hit_count: 11891, read_count: 554620, read_byte: 5.93 GB, read_time: 2.09s}}}	offset:0, count:1	N/A	N/A
    └─IndexFullScan_11	1.00	1	cop[tikv]	table:h_equip_bin_box_status_history, index:idx_gmt_create(gmt_create)	tikv_task:{proc max:472ms, min:33ms, avg: 186.8ms, p80:229ms, p95:280ms, iters:1829, tasks:1829}	keep order:false	N/A	N/A

还是mvcc的问题,等GC后清理 或手动compact

1 个赞

重建表,数据迁移下

删除大量数据后,会有很多无用的 key 存在,影响查询效率。要解决该问题,可以尝试开启 Region Merge 功能,具体可参考最佳实践中的删除数据部分。

实际上没用,合并不了,表数据清空region大小不会降低到触merge条件

delete_skipped_count: 19440216, key_skipped_count: 871167911
删除的数据没有真正gc掉
建议在业务低峰期进行手工compact操作

手工compact

手工compact没效果
一共6个节点,都执行过了

但是好像并没有被清理掉

执行提问里的查询还是非常慢

贴下select * from xxx limit 1的执行计划,还是和原来一样吗?

你这个执行是不是很快就结束了 ? 加-c write -d kv

没执行了2,3个小时

参考下面,只对这个表做compact ,加-c write -d kv

mysql -uroot -pXXX -hxxx -PXXX information_schema -e “select region_id from tikv_region_status where db_name=‘oltp’ and table_name=‘sbtest8’”>region_list
cat region_list|while read line
do
tiup ctl:v7.1.0 tikv --host xxxx:20160 compact -r $line -d kv -c write --threads 1 --bottommost force
tiup ctl:v7.1.0 tikv --host xxx:20160 compact -r $line -d kv -c default --threads 1 --bottommost force
done

1 个赞

limit 1变快了 但是目测是因为有缓存 limit100照样非常慢

Limit_7	1.00	1	root		time:2.1s, loops:2	offset:0, count:1	N/A	N/A
└─TableReader_11	1.00	1	root		time:2.1s, loops:1, cop_task: {num: 1445, max: 283ms, min: 181µs, avg: 1.42ms, p95: 1.92ms, max_proc_keys: 1, p95_proc_keys: 0, tot_proc: 995ms, tot_wait: 151ms, rpc_num: 1445, rpc_time: 2.04s, copr_cache_hit_ratio: 1.00, distsql_concurrency: 1}	data:Limit_10	540 Bytes	N/A
  └─Limit_10	1.00	1	cop[tikv]		tikv_task:{proc max:752ms, min:0s, avg: 376.1ms, p80:483ms, p95:552ms, iters:1445, tasks:1445}, scan_detail: {total_process_keys: 1, total_process_keys_size: 152, total_keys: 4129043, get_snapshot_time: 547.2ms, rocksdb: {delete_skipped_count: 270700, key_skipped_count: 4399736, block: {cache_hit_count: 6387, read_count: 1, read_byte: 64.0 KB, read_time: 64.7µs}}}	offset:0, count:1	N/A	N/A
    └─TableFullScan_9	1.00	1	cop[tikv]	table:h_equip_bin_box_status_history	tikv_task:{proc max:752ms, min:0s, avg: 376.1ms, p80:483ms, p95:552ms, iters:1445, tasks:1445}	keep order:false	N/A	N/A

GC时间是多长,现在只有27万是gc后的key,总共需要扫描439万

单表的compact之前我执行过 毫无效果 所以才全局compact的
现在在执行加了-c write的 执行的慢了好多… 一共要执行2w多次 有的等了
等执行完了再看看

SELECT concat( 'tiup ctl:v6.5.1 tikv --host ',ADDRESS,' compact -d kv -c write --threads 1 --bottommost force -r ',a),APPROXIMATE_SIZE from ( 
SELECT DISTINCT(trs.REGION_ID) as a,ADDRESS,APPROXIMATE_SIZE from TIKV_REGION_STATUS trs left join  TIKV_REGION_PEERS trp on trs.REGION_ID = trp.REGION_ID LEFT JOIN TIKV_STORE_STATUS tss  on tss.STORE_ID =trp.STORE_ID  where table_name = 

'h_equip_bin_box_status_history'  ORDER BY APPROXIMATE_SIZE desc) as tmp;

gc时间没动 默认的10分钟
他这里的27w和439w代表啥
是说我要查询1条记录要扫描439w条记录 其中27w是已删除但是未compact的吗 那剩下(439-27)w的数据是啥

另外-c write代表啥 没搜到文档介绍这个

可以看下这个: explain analyze 中的total_keys和key_skipped_count 的疑问? - #5,来自 Raymond

rocksdb里的2个CF:default/write 绝大部分数据都在这个CF里

delete_skipped_count: 270700, key_skipped_count: 4399736
delete_skipped_count已删除未gc的大概27万
key_skipped_count已标记gc但需要compact清除的大概439万
所以还是得compact
tiup ctl:v6.5.1 tikv --host ip:port compact -c write --bottommost force
把write CF也compact下看看吧

感谢各位大佬解答

compact了4天…终于compact完了

执行计划也对了

Limit_7	100.00	100	root		time:1.86ms, loops:2	offset:0, count:100	N/A	N/A
└─TableReader_11	100.00	100	root		time:1.85ms, loops:1, cop_task: {num: 3, max: 761.3µs, min: 476.1µs, avg: 575.4µs, p95: 761.3µs, max_proc_keys: 100, p95_proc_keys: 100, rpc_num: 3, rpc_time: 1.7ms, copr_cache_hit_ratio: 0.33, distsql_concurrency: 1}	data:Limit_10	14.5 KB	N/A
  └─Limit_10	100.00	100	cop[tikv]		tikv_task:{proc max:121ms, min:0s, avg: 40.3ms, p80:121ms, p95:121ms, iters:5, tasks:3}, scan_detail: {total_process_keys: 100, total_process_keys_size: 15234, total_keys: 102, get_snapshot_time: 87.6µs, rocksdb: {key_skipped_count: 100, block: {cache_hit_count: 24}}}	offset:0, count:100	N/A	N/A
    └─TableFullScan_9	100.00	100	cop[tikv]	table:h_equip_bin_box_status_history	tikv_task:{proc max:121ms, min:0s, avg: 40.3ms, p80:121ms, p95:121ms, iters:5, tasks:3}	keep order:false	N/A	N/A

底层没做分区么,分区之后删除很快,而且这种我觉得做一个迁移,然后truncate是不是更好

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