大数据量级关系型数据库分页优化方案

1.缘起~

相信大多程序员在经历的工作中都会遇到 大数据表(mysql)的分页慢查询问题。在一家b2b做院线与影院系统时,单表影片以及单表订单量两千万+(沉淀了两年的数据)。在当时现有的技术架构上做查询分页优化十分艰难。下面说说 当时的优化经历以及尝试的方案。补充说明下架构实现方面的手段。

 

2.为什么大数据表的分页越往后越慢?

究其原因 要从根源说起,mysql 分页通常使用的是limit 分页那么下面分析下他的分页原理。我们可以通过explain 查看如下情况的分页sql 执行计划:

偏移量(limit 偏移量 每页显示条数)

2.1 偏移量: 1000 + 10

 

2.2 偏移量: 1W + 10

 

2.3 偏移量: 100W + 10

 

2.4 偏移量: 400W + 10

 

2.5 偏移量: 1000W + 10

 

 

综上你会发现:执行时间随着数据的增加而增加指数增长。

查询表数据千万级时,越往后分页查询越慢。比如查询1000W + 10 页数据时,mysql 会扫描1000w + 10 条数据然后丢弃前1000w 条数据。慢就慢在扫表1000w上。所以我们只要控制查询扫描的行数就可以提高查询速度了。怎么控制扫描的行数呢?

 

3.解决方案:

当时因为架构设计上 我们数据库表ID是 自增所以有序,而且根产品有约定好 可以允许 分页有误差,也就是 即便ID不连续了 那么业务上也是可以容忍的。--- 有容奶大。。。。。

3.1 最大ID查询法。

就是将有序的ID(比如自增的ID)作为检索条件限定查询扫描表数据的条数。

如: select * from table1 where id > 10W limit 10W 10 ;

由于ID会有索引定位到 ID > 10W 会很快而且是直接定位。那么从10W 开始获取10条 结果集返回这个查询会非常快 只需要0.009s

 

3.2 THE another one

使用between and

这个方式也要求ID是有序且自增不间断无断裂

select * from table1 where id between 10W and 10W+10;

 

3.3 limit id

其实这种方式也是通过ID 的方式解决问题:

select * from table1 where id > (select id from table1 limit 10W, 1) limit 10;

先通过扫描 ID索引获取到 第10W条数据的ID 然后从此ID往后数 10条拿出来;

扫描有索引的ID 速度会很快;

4.架构设计生的其他优化手段:

4.1 分库分表:

垂直分库分表,水平分库分表;

4.2 冷热备份:

对数据进行冷备 和热备份;

4.3 使用非关系行数据库:

例如mongodb 他的客户端做的几户可以和关系型数据库相媲美

 

4.4 使用查询缓存,对热点数据缓存;

这种优化方案可能对于 大数据量分页慢的问题没有什么帮助。

林林种种 说了好些方法,但他们的应用通常都会带来其他维度的“开销”。比如水平拆分表的话那么跨表查询问题?? 改变现有架构添加分表逻辑或者引入分表中间件等问题?? 所以优化方案的选取通常要结合 业务场景以及项目架构场景,综合选取最适合的方案。

---- 只有最适合 没有最好。脱离业务 场景的 架构 & 优化 都是瞎扯淡。

 

你可能感兴趣的:(MyBatis,mysql,Spring,数据库,mysql,大数据)