我们说一下,对于持续增长的数据,如何累加数据

毕竟数据库所有的操作,本质上都会先进行查询操作,只有找到了数据才能对数据进行操作,所以性能的一个瓶颈,就是查询的快慢问题

而查询所依靠的因素,主要是

查询的时间复杂度

数据总量

而和查询的时间复杂度相关的条件,取决于对应的数据结构和算法,但是在MySQL中,这两者是固定的,所以我们唯一能改变的,就是总量了

我们解决海量数据导致存储系统变慢的问题,简单来说就是拆,将所有数据拆分成分片 shard,然后拆出来的每个分片的数据就是可以接受的了

接下来,我们就是如何拆分数据的问题

我们拿一个如何存档历史订单来说明如何提升查询性能,首选的就是归档历史订单

所谓归档,就是拆分数据的策略,简单就是将大量的历史订单移到历史库

毕竟,对于订单表这些热点表,大部分就是访问的最近的数据,订单表中有大量的数据都是不常用的老数据

因为新数据只占数据总量的相对较少的一部分,所以新老数据分开后,新数据就会少很多,查询速度会块很多,老数据虽然和之前比没少多少,但是放在额外的一个表,减少了热点的出现

因为只有查询统计类的功能,会查询历史订单,所以可以简单的按照时间,去查询订单表

大致的流程如下

图片

首先创建一个和订单一样的历史订单表

然后,将数据分批查出来,导入到历史订单表

然后验证能不能走历史订单表,查看代码是否有bug,如果有bug,可以回滚代码,并不影响数据

如果代码无误,删除订单表的冗余数据

然后利用一个脚本,进行批量的导表

接下来,如何删除大量的数据

我们如何从订单表中删除已经迁走的历史数据,直接一口删除,可能因为删除的数据量大,导致阻塞时间过长,所以我们可以分批删除

比如每次删除1000条,进行分批的删除

sql的基本书写如下

delete from orders

where timestamp < SUBDATE(CURDATE(),INTERVAL 3 month)

order by id limit 1000;

执行删除语句的时候,每次删除之间最好可以停顿一秒,直到全部删除

然后更快方便快捷的方式是

只要数据的主键ID是具有自增性的

我们先去timestamp上找出所有符合的记录,然后按照订单ID排序,之后删除之前的1000条数据

我们可以先进行一次查询,找到符合条件的历史订单的最大的订单ID,然后在删除的语句中将删除的依据设置为按照主键删除

这样就避免了回表操作,而且由于Id是有序的,在B+树的有序性,保证了这些Id也是有序的

在删除之后,我们检测一下MySQL占用的磁盘空间,并没有变少,这是因为MySQL只是将其标记可以重新写入,并没有实际的删除

如果需要删除,我们可以执行以下OPTIMIZE TABLE来释放存储空间,这相当于重建一下表,执行过程中会一直锁表,这是需要注意的

除此外,还可以重新新建一个临时表,然后将当前订单的表复制到临时表中,然后修改表明,最后将临时表的名字改为正式表,这相当于手工重新建表

基本SQL如下

— 新建一个临时订单表

create table orders_temp like orders;

— 把当前订单复制到临时订单表中

insert into orders_temp

select * from orders

where timestamp >= SUBDATE(CURDATE(),INTERVAL 3 month);

— 修改替换表名

rename table orders to orders_to_be_droppd, orders_temp to orders;

— 删除旧表

drop table orders_to_be_dropp

对于订单这种具有时间属性的表,我们可以利用上卖弄说的拆分方式将旧数据归档,可以起到一个良好的效果,需要注意的是我们重建订单表的方式方法

思考一下:

对于订单库,对比一下分库分表和归档历史订单拆分

相较于直接分库分表,归档历史订单更加的灵活,可以将历史的订单,迁移到查询更快的系统中

直接分库分表,会遇到冷热不均的问题

发表评论

邮箱地址不会被公开。 必填项已用*标注