分库分表下分页查询解决方案

让人想犯罪 __ 提交于 2019-11-28 13:20:45

分库分表下分页查询解决方案

不管是随着业务量的增大、还是随着用户数量的增长,在单一表中无法承受大量大数据,导致查询速度极慢甚至拖垮数据库。所以分库分表的策略随之应用,但是如何在分库分表的情况下,进行分页查询,目前仍是业界难题。
本文记录了三种情况下,对于分库分表下的分页查询优化方案。

1 目前大多数的解决方案

不管是目前的一些数据库中间件例如Mycat,还是ElasticSearch下的分片查询,大多都使用了最简单的策略去实现不同存储下的全局有序查询,即在每次分页查询时,查询所有存储下相应的条数,汇总排序得到最终要展示的分页下的数量。
这种策略实现方案简单、精度高,但是随着查询页数的增长,不管是内存的占用还是查询速度都会极具上升。因此,如果要采取这种方案,要考虑到对于查询页数的限制,防止影响应用的运行。

2 APP上的下拉式分页

在APP上的分页查询,多数是采用了下拉式分页(向下拖动,会出现新的一页)。在这种情况下,用户无法自由的选取要查询的页数,因此可以采用以下方式来优化分页的性能。
举个简单的例子,查询需要涉及到五个ES的索引,每页分页数量是10。
1.当用户请求第一页数据时,从五个索引中分别查询前十条。
2.分别记录五个索引中的数据截止位置,例如

索引1 索引2 索引3 索引4 索引5
3 2 0 4 1

将该数组存储到用户相关的缓存下。
3.用户请求下一页数据时,先查询上一页的用户分页缓存,从缓存中获取到上一页的截止位置,3、2、0、4、1。从对应索引的截止位置当起始位置,分页查询十条。
4.用户请求的页数为第一页时,清除缓存,重复1-4步骤。

该策略不会出现当页数过多时,应用负载过高的情况,但是前提条件为用户不能跨页查询。

3 普通的分页查询

在一些后台管理页面中,分页查询是要能支持跨页查询的,这样就无法使用上一种的策略了,但是还可以想办法做出一些优化。

3.1 查询精度要求很低

如果对查询精度没有要求的话,可以使用一种简单的策略,还是拿上面的例子还说明:
查询需要涉及到五个ES的索引,每页分页数量是10。
那么第一页查询分别查询五个索引的0-10条数据再排序返回前十条。
第二页查询分别查询五个索引的10-20条数据再排序返回前十条。

简单、性能高,但是问题也是显而易见的,查询的精度很低,可能会漏掉许多数据,但是每页数据无重复。

3.2 查询精度一般

网上广为流传的二次查询策略,该策略的数据精度比上一种方案有了明显的提高。具体内容如下
条件:查询需要涉及到五个ES的索引,每页分页数量是10。

  1. 求得每个索引的查询条数actualPageSize,用每页查询的数量 整除 索引数量。
    即actualPageSize = pageSize / indexSize
  2. 查询每个索引下相应页数的actualPageSize条,
    即 limit page * actualPageSize,actualPageSize
  3. 汇总所有索引的查询,排序得到最小的记录的标识符minId(如果主键是自增就是id,主键不是自增就是创建时间cmt_created),并记录每个索引各自的最大的记录的标识符maxId。注意,minId只有一个,maxId每个索引都有自己的一个。
  4. 在每个索引中,使用between minId,maxId 查询相应的结果后汇总排序,得到前十条记录返回。

该种策略查询数据的精度比较高(在数据为随机分配的情况下,精度可为百分百),且不会出现数据丢失,但会出现数据重复,即上一页的数据在下一页中还能看到。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!