看到分页查询的第一个念头应该是:能不能在不同的表上平均分页查询数据,得到的结果合并在一起就是分页的结果
例如,查询中的语句是这样的
SELECT * FROM order_tab ORDER BY id LIMIT 4 OFFSET 2
因为本身有两张表,可以改成这样
SELECT * FROM order_tab_0 ORDER BY id LIMIT 2 OFFSET 1
SELECT * FROM order_tab_1 ORDER BY id LIMIT 2 OFFSET 1
在每一张表都查询从偏移量1开始的2条数据,那么合并在一起就可以认为从全局的偏移量2开始的4条数据。
图里我们能够看出来,按照道理全局的 LIMIT 4 OFFSET 2 拿到的应该是 3、4、5、6 四条数据。但是这里我们拿到的数据却是 2、4、5、9。这也就是这个方案的缺陷:它存在精度问题。也就是说,它返回的数据并不一定是全局最精确的数据
那么这个方案是不是就不能用了呢?并不是的,在一些对顺序、精度要求不严格的场景下,还是可以用的。例如浏览页面,你只需要返回足够多的数据行,但是这些数据具体来自哪些表,用户并不关心。
关键词就是平均分页
在一些可以接受分页结果不精确的场景下,可以考虑平均分页的做法。举个例子来说,如果查询的是 LIMIT 4 OFFSET 2,并且命中了两张目标表,那么就可以考虑在每个表上都查询 LIMIT 2 OFFSET 1。这些结果合并在一起就是 LIMIT 4 OFFSET 2 的一个近似答案。这种做法对于数据分布均匀的分库分表效果很好,偏差也不大。
这个方案还有一个进阶版本,就是根据数据分布来决定如何取数据。
更加通用的做法是根据数据分布来决定分页在不同的表上各自取多少条数据。