设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

炸!业界难题,跨库分页的几种常见方案(2)

发布时间:2019-05-14 23:37 所属栏目:21 来源:58沈剑
导读:缺点显而易见: 每个分库需要返回更多的数据,增大了网络传输量(耗网络); 除了数据库按照time进行排序,服务层还需要进行二次排序,增大了服务层的计算量(耗CPU); 最致命的,这个算法随着页码的增大,性能会急剧下

缺点显而易见:

  • 每个分库需要返回更多的数据,增大了网络传输量(耗网络);
  • 除了数据库按照time进行排序,服务层还需要进行二次排序,增大了服务层的计算量(耗CPU);
  • 最致命的,这个算法随着页码的增大,性能会急剧下降,这是因为SQL改写后每个分库要返回X+Y行数据:返回第3页,offset中的X=200;假如要返回第100页,offset中的X=9900,即每个分库要返回100页数据,数据量和排序量都将大增,性能平方级下降。

“全局视野法”虽然性能较差,但其业务无损,数据精准,不失为一种方案,有没有性能更优的方案呢?

“任何脱离业务的架构设计都是耍流氓”,技术方案需要折衷,在技术难度较大的情况下,业务需求的折衷能够极大的简化技术方案。

方案二:禁止跳页查询法

在数据量很大,翻页数很多的时候,很多产品并不提供“直接跳到指定页面”的功能,而只提供“下一页”的功能,这一个小小的业务折衷,就能极大的降低技术方案的复杂度。

炸!业界难题,跨库分页的几种常见方案

如上图,不能跳页,那么第一次只能够查第一页:

(1)将查询

  1. order by time offset 0 limit 100; 

改写成

  1. order by time where time>0 limit 100; 

(2)上述改写和offset 0 limit 100的效果相同,都是每个分库返回了一页数据(上图中粉色部分);

炸!业界难题,跨库分页的几种常见方案

(3)服务层得到2页数据,内存排序,取出前100条数据,作为最终的第一页数据,这个全局的第一页数据,一般来说每个分库都包含一部分数据(如上图粉色部分);

这个方案也需要服务器内存排序,岂不是和“全局视野法”一样么?第一页数据的拉取确实一样,但每一次“下一页”拉取的方案就不一样了。

点击“下一页”时,需要拉取第二页数据,在第一页数据的基础之上,能够找到第一页数据time的最大值:

炸!业界难题,跨库分页的几种常见方案

这个上一页记录的time_max,会作为第二页数据拉取的查询条件:

(1)将查询

  1. order by time offset 100 limit 100; 

改写成

  1. order by time where time>$time_max limit 100; 

炸!业界难题,跨库分页的几种常见方案

(2)这下不是返回2页数据了(“全局视野法,会改写成offset 0 limit 200”),每个分库还是返回一页数据(如上图中粉色部分);

炸!业界难题,跨库分页的几种常见方案

(3)服务层得到2页数据,内存排序,取出前100条数据,作为最终的第2页数据,这个全局的第2页数据,一般来说也是每个分库都包含一部分数据(如上图粉色部分);

如此往复,查询全局视野第100页数据时,不是将查询条件改写为

  1. offset 0 limit 9900+100;(返回100页数据) 

而是改写为

  1. time>$time_max99 limit 100;(仍返回一页数据) 

以保证数据的传输量和排序的数据量不会随着不断翻页而导致性能下降。

方案三:允许数据精度损失法

“全局视野法”能够返回业务无损的精确数据,在查询页数较大,例如第100页时,会有性能问题,此时业务上是否能够接受,返回的100页不是精准的数据,而允许有一些数据偏差呢?

先来了解一下,数据库分库-数据均衡原理。

什么是,数据库分库-数据均衡原理?

使用patition key进行分库,在数据量较大,数据分布足够随机的情况下,各分库所有非patition key属性,在各个分库上,数据分布的统计概率情况是一致的。

例如,在uid随机的情况下,使用uid取模分两库,db0和db1:

  • 性别属性,如果db0库上的男性用户占比70%,则db1上男性用户占比也应为70%;
  • 年龄属性,如果db0库上18-28岁少女用户比例占比15%,则db1上少女用户比例也应为15%;
  • 时间属性,如果db0库上每天10:00之前登录的用户占比为20%,则db1上应该是相同的统计规律;

炸!业界难题,跨库分页的几种常见方案

利用这一原理,要查询全局100页数据,只要将:

  1. offset 9900 limit 100; 

改写为

  1. offset 4950 limit 50; 

即每个分库偏移一半(4950),获取半页数据(50条),得到的数据集的并集,基本能够认为,是全局数据的offset 9900 limit 100的数据,当然,这一页数据并不是精准的。

根据实际业务经验,用户都要查询第100页网页、帖子、邮件的数据了,这一页数据的精准性损失,业务上往往是可以接受的,但此时技术方案的复杂度大大降低了,既不需要返回更多的数据,也不需要进行服务内存排序了。

画外音:如果业务能够接受,这种方案的性能最好,强烈推荐。

方案四:二次查询法

有没有一种技术方案,即能够满足业务的精确需要,无需业务折衷,又高性能的方法呢?这就是接下来要介绍的终极武器,“二次查询法”。

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读