关于Mysql大表的数据归档

  • 网站日常运行中,一些业务和日志类的表数据会越来越多,达到千万以上时,涉及到的联表等复杂查询会越来越慢,同时也会占用越来越大的磁盘空间。此时我们可以保留一段时间内的数据,其他日期久远的数据我们可以根据情况进行删除或归档。
  • 根据常规认知,不管是直接删除无效数据还是归档无效数据后,清空原表的无效数,都需要使用delete语句删除。然而根据博主敖丙的文章为什么MySQL不建议使用delete删除数据中给出的测试结果来看,直接在100万数据的表中使用delete删除50w条数据后,不仅该表占用的磁盘空间未减小,同时执行查询的效率也没有提高。这是因为MySQL内部不会真正删除空间,而且做标记删除,即将delflag:N修改为delflag:Y,commit之后会会被purge进入删除链表,如果下一次insert更大的记录,delete之后的空间不会被重用,如果插入的记录小于等于delete的记录空会被重用
  • 此时我们为了真正的清空无效数据占据的空间,我们可以使用表分区的分区交换方法来达到该目的。
  • 首先,要确保要操作的表order为分区表,不是分区的表现改造为分区表(表中数据较多时直接改造为分区表耗时较长,可先创建一个相同结构的分区表后,通过dataX把数据导入到分区表中)
  • 然后,建立一个普通中间表middle,结构与分区表相同,再创建一个归档分区表order_bak
  • 最后,分区交换。
    先把一个无效分区下的数据导入到中间表中
alter table order exchange partition p201808 with table middle;

把中间表中的数据,导入到归档表中对应的分区中

alter table order_bak exchange partition p201808 with table middle;

最后把order表中的p201808 分区删除即可

  • 这样原表和归档表都是按月的分区表,只需要创建一个中间普通表,在业务低峰期做两次分区交换,既可以删除无效数据,又能回收空间,而且没有空间碎片,不会影响表上的索引及SQL的执行计划。
  • 我们不可能一次把所用分区都建好,我们需要做一个定时任务,每个月初或月末时,给原表和归档表追加分区后,再执行归档操作

猜你喜欢

转载自blog.csdn.net/u012830303/article/details/111629728
今日推荐