数据库常见面试题:分库分表之后如何进行分页查询
我们为了提升数据库的查询性能,进行了分库分表。但分表一时爽,虽然性能提升了,却也同时遇到了很多问题。其中,分页查询就是一个常见问题,很多小伙伴在前几期的评论区也提到过类似问题。
其实说到分页查询,真正好用的方案不多,而且需要看具体的场景以及分表的策略。比如说,如果按照时间点分表或者 ID 的范围分表,恰好又是按照这个时间查询,那么在分页的时候就很容易。我们可以根据时间范围的条件先找到对应的表,然后按照传统的单表分页查询的方法就行。这是一种比较容易的分表场景,利用的是实际的范围或者是 ID 的范围来分表。
但是,如果是取模的场景,不具备连续性,数据分散得比较厉害,在各个表中。这个时候如果想要分页,比如分页找近期注册的一万个用户,每页十条数据,那么就需要在每一个用户表查询每个表近期落库的十个数据,然后再根据注册的时间排序找到前十个。这种策略比较简单也很实用。一开始前几页的查询还可以,因为数据量不大,查询的速度还是很快的。但是一旦查询到了后面,比如几百页,那么每个表都要把前面的数据全部捞出来再聚合再排序,速度就会很慢。包括一些中间件,比如 MyCat,一旦查询的页码比较大的时候,速度也都会慢下来。
这时候可以做一些改造,比如查询的时候带上上一页的 ID 。这样在查询下一页数据的时候,就可以根据 ID 的范围先做一些筛选,就可以过滤掉很多的数据,还是相当实用的。但是这个依赖上一页的数据,所以不能跳页,得一页一页的查询。
其实对于固定的条件查询,包括一些数据报表涉及到分页的,我个人建议可以先提前算好放在数据库里面。比如说像用户表,要查询近一周的注册的数据,就可以提前查询好近一周注册的数据放在一个单独的数据表里面,然后定时刷新。这样在查询的时候就可以直接捞取,不需要再做一些分页的策略运算,分页的速度很快。这种属于大数据里面以空间换时间的思想,除了分页,像一些复杂的运算都可以运用。大家在日常的开发过程中都可以借鉴一下。