无论采用哪种存储系统,数据查询的耗时取决于两个因素
- 查找的时间复杂度
- 数据总量
查找的时间复杂度又取决于
- 查找算法
- 数据存储结构
以Mysql存储的订单数据为例,随着业务的发展,数据量越来越大,对一些历史归档数据的查询,如果直接从DB查询就不太合适,比如"2021年订单"等等。这是就适合对数据进行归档。
数据要归档到哪里呢?
根据业务的需要,可以归档到另外的Mysql数据库,也可以归档到另外的存储系统。比如MongoDB、ES、HBase、ClickHousse
归档步骤:
1. 从Mysql中查询需要归档的数据
2. 将数据写入新的存储系统
3. 删除原Mysql数据
归档过程需要关注的问题:
1. 能够随时暂停归档任务,随时开始归档任务
2. 能够记录归档任务的执行状态
3. 归档任务不能影响正常的业务系统, 注意避免内存溢出
3. 要保证归档后的数据与原数据的一致性
归档具体实现(以迁移到MongoDB为例):
1. 从mysql分页查询数据, 查询条件有 id > ${maxOrderId}, 对应MongoDB记录的已迁移的最大orderId.
select * from ${orderTableName} o
left join ${orderItemTableName} ot
on o.id = ot.order_id
where o.id >= #{maxOrderId} and o.gmt_create< #{gmtCreate}
order by id limit #{limit}
2. 数据写入MongoDB, 另外,MongoDB记录写入的最大orderId(orderId增序), 两个操作在一个事务中。
3. 删除mysql迁移的这批数据
<delete id="deleteMigrateOrders">delete from ${orderTableName} oWHERE o.order_id >= #{minOrderId} and o.order_id <= #{maxOrderId}order by id</delete>
- 之所以使用orderId作为条件,因为orderid是主键,查询更快.
- 为什么要增加排序呢? 因为按照ID排序后, 每批删除的记录基本上都是ID连续的一批记录,
由于B+树的有序性,这些ID相近的记录,在磁盘的物理⽂件上,⼤致也是存放在⼀起的,这样删除效率会⽐较⾼,也便于MySQL回收⻚。
4. ⼤批量删除数据,还要注意下,执⾏删除语句后,最好能停顿⼀⼩会,因为删除后肯定会牵涉到⼤量的B+树⻚⾯分裂和合并,这个时候MySQL的本身的负载就不⼩了,停顿⼀⼩会,可以让MySQL的负载更加均衡。