怎么实现跨库分页查询?

1 个回答

  • 东方朔
    重新审视自己,什么使你快乐,什么就是眼下最珍贵。
    ### 全局视野法 就是例如要查询第三页的数据,那么把每个库里面前三页的数据都查询出来,然后排序, 优点是比较准确,也比较简单 问题就是每个库返回的页数很多,网络传输量很大,而且收到数据后的需要二次排序,排序的性能消耗也比较大。 ```java 要查order by time offset offset_value limit num时 对每个库查 order by time offset 0 limit offset_value + num然后进行排序 ``` ### 最大时间法 就是禁止跳页查询,就是如果业务不需要跳页查询的话,一开始查第一页的时候,从每个库取一页数据回来进行排序后返回。 查第二页数据时根据第一页结果中最大的时间去每个库再取一页数据,然后进行排序得到第二页数据。 优点是是每次直插一页,传输数据量小,排序的数据量也小, 缺点是由于查第二页及以后的页数都需要知道上一页最大时间。 ```java 要查order by time offset offset_value limit num时 获得上一页的最大时间 对每个库查 where time >lastTime order by time offset 0 limit num然后进行排序 ``` ### 每库平均取法 假设数据分布足够平均,每个库的数据分布都是平均的,假设有四个库,查第一页数据时,每个库都取前0.25页数据,然后合并后返回,取第二页数据时,每个库再都取0.25页。但是这样取得是不准的数据。 ```java 将order by time offset X limit Y,改写成order by time offset X/N limit Y/N ``` ### 二次查询法 假如要取offset 为X,limitY的数据, 1.假设有四个库,需要去每个库查offset为X/4,limit为Y的数据,然后得到四个结果集,每个结果集的time都有一个时间最小的time_min,时间最大的time_max结果,取四个结果集中最小的time_min 2.然后去每个库去查between time_min到之前每个库的time_max的结果集, 3.因为之前每个库的time_max的offset都是X/4+Y,所以可以反推出time_min在每个库里的offset,然后得到全局offset, 4.然后根据全局offset可以计算我们想到的offset X后Y个数据,就是以time_min为起点到距离我们offset的差值。 关键在于两次查询中间,如果数据库删除过这个区间内的数据,time_min到time_max之间删除过数据,这样就不准, ```java (1)将order by time offset X limit Y,改写成order by time offset X/N limit Y (2)找到最小值time_min (3)between二次查询,order by time between time_min and time_i_max (4)设置虚拟time_min,找到time_min在各个分库的offset,从而得到time_min在全局的offset (5)得到了time_min在全局的offset,自然得到了全局的offset X limit Y ``` 首先需要查询两次,而且如果表数据是按照分段来查询的,会有问题。 参考链接: [https://blog.csdn.net/uiuan00/article/details/102716457](https://blog.csdn.net/uiuan00/article/details/102716457) Zset记录法 例如像百度贴吧,假设一个吧里面允许跳页查询的页数为前100页,每页为20个,,每次顶贴都会把贴子顶到最前面,那么可以使用一个Zset来存储最近的2000个帖子的基本信息(id,标题,图片,等足够贴吧列表页展示的信息),每个帖子的score就是最近更新时间,帖子在Zset中按照更新时间排序。然后每次顶贴都来维护这个Zset就可以了。跳页也可以直接以Log(N)复杂度去Zset中查询到这个帖子。
    发布于 2022-02-09 20:26 •IP属地 湖北
    举报
    评论
    收藏