分库分表后的分页查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分库分表后的分页查询相关的知识,希望对你有一定的参考价值。

参考技术A 如果要获取第N页的数据(每页S条数据),则将每一个子库的前N页( offset 0,limit N*S )的所有数据都先查出来(有筛选条件或排序规则的话都包含),然后将各个子库的结果合并起来之后,再做查询下 top S (可不用带上相同的筛选条件,但还要带上排序规则)即可得出最终结果,这种方式类似es分页的逻辑。

如果要获取第N页的数据,第一页时,是和全局视野法一致,但第二页开始后,需要在每一个子库查询时,加上可以排除上一页的过滤条件(如按时间排序时,获取上一页的最大时间后,需要加上 time > $maxTime_lastPage 的条件;如果没有排序规则,由于是默认主键id的排序规则,也可加上 id > $maxId_lastPage 的条件),然后再 limit S ,即可获取各个子库的结果,之后再合并后 top S 即可得到最终结果。在类似app中列表下拉的场景中,业务上可以禁止跳页查询,此时可以使用这种方式。

在大数据量的前提下,需要查询的数据,从概率论角度,是均匀分布在各个字库中的,因此可以假定需要查询的第N页数据,在子库中都处于第 N/X 页的前 S/X 条中(X=子库数);所以查询子库时,限定 offset ((N/X)-1)*S/X,limit S/X 即可,例 N=S=100,X=2 时,子库分页条件为 offset 4950,limit 50 ;然后合并子库结果后即可得出最终结果,当然这个结果是不准确的。在类似网页回帖上的场景下,往往数据精度要求不太高,此时可以使用这种方式。

也是在大数据量的前提下,依据概率论,可以假定需要查询的第N页的数据,在子库中都处于第 N/X 页的后面。然后可按如下步骤查询:

1). [第一次查询] 按指定条件(筛选条件或排序规则条件)查询各个子库的S条数据,即 offset ((N/X)-1)*S/X,limit S
2). 如果没有排序规则条件,则默认主键id排序,那么获取各个子库的返回数据的最小值和最大值: min_i_id,max_i_id ;如果有排序条件,就按排序条件获取
3). 比较各个子库的 min_i_id ,得到最小的,定义为 min_id
4). [第二次查询] 再次查询(有筛选条件的话也要包含)各个子库,加上条件: min_id<id<max_i_id ;(注: min_i_id = min_id 的子库可省略查询)
5). 查看第二次查询结果中, min_id_id != min_id 的其它子库中,共多了几条数据,如果多了M条,则可以得出全局中,min_id前面的数据有 (((N/X)-1)*S/X)*X - M => ((N/X)-1)*S-M 条, ((N/X)-1)*S-M 即为 min_id 的全局offset
6). 计算真正的全局offset: ((N-1)*S) 和 min_id 的全局offset: ((N/X)-1)*S-M 之间的差值K,由公式可得: K>=0
7). 合并第二次查询的各子库结果,并按id排序后,以 K为offset,S为limit 即可得到最终全局的分页结果

参考: https://mp.weixin.qq.com/s/H_2hyEqQ70Y_OoFZh_P_5A

mysql分库 分页查询

Mysql海量数据分表分库如何列表分页?

1.现在使用ElasticSearch了。基于Lucene的解决方案

2.必须将mysql里的数据写入到类似hbase这样的分布式数据库,查询快。但分页、查询的话,可以在hbase前加一层solr,用于建立数据索引

 

 

如何对分库后的数据进行分页查询?

yeyingsheng 发布于 2015/04/21 10:18
 
阅读 7K+
 
收藏 1
 
 si项目,现在连接6台mysql数据库,路由分库算法是根据id的hash值%6,根据值不同分别存入6台数据库。现在不知道如何做分页查询列表,请问有谁知道吗 
 
 
收藏 (1)
 
0
 
 
技术分享图片
三阶魔方 

1、直接使用跨库的多表联合查询。不建议。

2、向6台数据库server均发送一个查询请求,然后对所有查询结果进行汇总,再处理分页逻辑。

3、建立一个总数据库,只负责维护主键和必要的索引,以供分页查询。

4、使用redis维护一个主键序列,分页操作就是截取该序列的一部分,其结果就是主键id集合。拿到id后便可以映射到多台mysql服务器上查询数据了。但毕竟数据被分布式存储了,取到完整结果集必须要多次、多台的数据库访问,这个肯定是避免不了。

注:“多台”数据库访问的问题无解,但同台“多次”数据库访问的问题可以通过程序优化。

 
技术分享图片
yeyingsheng 
感觉使用redis维护一个主键序列比较靠谱一点,但是没有用过
 
0
 
 
技术分享图片
hylent 
另建一个主库,有所有分库的数据
技术分享图片
yeyingsheng 
回复 @hylent : 你说的也挺有道理,不知道大家采取最多的方式是什么?
技术分享图片
hylent 
回复 @1157624952 : 嗯,单点,可以主备。最佳答案中的,在redis里维护索引的方法,也不错,不过,就要和业务挂钩了,多种排序方式需要维护多个序列。不过我还是觉得,数据放在内存中不太稳妥。。
技术分享图片
yeyingsheng 
这样的话就会出现主机单点问题了
 
0
 
 
技术分享图片
Jack_Q 
有没有使用cobar或mycat
技术分享图片
yeyingsheng 
没有使用
 
0
 
 
技术分享图片
Brin想写程序 

复杂查询情况下,只去前20页的内容。。也就是默认取200条,然后200*10做好排序,然后去前200条,分20页给用户显示出来。

对于基于日期,序号的有序数组的分页,可以记录当前分页最后一个的被分页的值,作为stub,然后往后组装。

技术分享图片
Brin想写程序 
回复 @1157624952 : 直接查各个数据库啊。。跟路由算法没关系。。
技术分享图片
yeyingsheng 
@Brin想写程序 额,我是根据路由算法插入相应的数据库的,没法每个查啊
技术分享图片
Brin想写程序 
回复 @1157624952 : limit 200,每个表都执行一遍。。
技术分享图片
yeyingsheng 
但是我如何去取前二十页呢
 
0
 
 
技术分享图片
hylent 

单纯就索引来说的话,可以试试一些专门做全文索引的服务软件。

不过这个只是我的想法,功能上应该可以,没实际中这样跑过,不知道稳定性怎么样

技术分享图片
yeyingsheng 
这个没有试过
 
0
 
 
技术分享图片
郭幻程 

向每个库发送同样的数据,汇总,排序,分页

为毛不用mycat

 
 
0
 
 
技术分享图片
匿名t3a 

你需要一个中间件

试试 Amoeba for MySQL 看看行不行

以上是关于分库分表后的分页查询的主要内容,如果未能解决你的问题,请参考以下文章

如何对分库后的数据进行分页查询

SqlServer 多表查询分页

mysql分库 分页查询

mysql 数据库 分表后 怎么进行分页查询?Mysql分库分表方案

亿万级分库分表后如何进行跨表分页查询

你们要的MyCat实现MySQL分库分表来了