美文网首页
如何进行大表删除

如何进行大表删除

作者: 啥也不说了 | 来源:发表于2018-09-14 21:28 被阅读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以上的大表中的数据

    相关文章

      网友评论

          本文标题:如何进行大表删除

          本文链接:https://www.haomeiwen.com/subject/dcdagftx.html