如何进行大表删除

2018-09-14  本文已影响33人  啥也不说了

背景

需要每天删除过期的数据。例如其中一个表是8亿行,400gb左右,一共是4天的数据。每天会有一天的数据过期,并且有新一天的数据进入。即每天需要删除2亿行左右。时间分区字段years_per_slice有单独索引。
简单的总结需求:删除某一天的数据。
使用的删除方案是

delete from table_test where years_per_slice='2018-09-12' limit 1000

遇到的问题

主要有两个问题:1、删除速度慢,所有表加起来要八小时左右;2、每次删除遇到了慢查询。

解决方案

网上资料

网上提到了一些解决方案,避免了删除导致锁表影响查询的问题,这些方案解决的问题不是我的问题。
也有一些使用新表存储有用数据然后删除旧表的方案,可以部分满足我的需求。但是我的部分表存储几十天数据,但是需要废除一天的数据,这种方案不适合,因为要保留的数据比要删除的更多。

自己的解决方案

原因分析

  1. 虽然时间分区有索引,且起作用了,但是使用
delete from table_test where years_per_slice='2018-09-12' limit 1000

的时候,是先根据years_per_slice做排序,然后取出前1000条。这个排序就会导致执行超时。

解决方案

1、先去查询需要删除的id:

select id from table_test where years_per_slice='2018-09-12' limit 1;

因为id是主键所以有索引,不会回表,这个查询非常快,得到一个id为a。

select * from table_test where years_per_slice='2018-09-12' limit 1;的时间会远远大于select id

2、确定删除范围
minId = a-limit/2;
maxId=a+limit/2;

为什么要要减掉减掉一半?因为select id的时候没有指定顺序,有可能不是按升序,所以通过减一半的方式确保数据可以肯定完全删除完

3、用id和时间替代limit

delete table table_test where years_per_slice='2018-09-12' and id between minId and maxId;

这样删除速度会非常快。

参考资料

MySQL删除大量数据的一些建议
mysql 删除大表中的数据】如何删除100G以上的大表中的数据

上一篇下一篇

猜你喜欢

热点阅读