分页,是每一个开发者必然会面临的一个问题。由于数据量大,不可能全部加载出来放置内存中,然后在页面展示。
分页的方式很简单,每次请求的时候,获取总记录数totalCount,然后根据每页要请求的记录数pageSize和当前页码pageNum,判断pageNum是否大于totalCount/pageSize。如果大于说明没有下一页了。
这种方式的优点:
1、简单明了,逻辑清晰。
2、实时查询,数据准确。
缺点:IO次数太多,每次查询都要请求两次sql。增加DB压力(DB资源很稀缺,而且每次查询总记录数是一次全表扫描,进行的是表级锁)
优化一:
只有首次的时候查询总记录数totalCount,再根据pageSize获取总共的页数,然后和当前pageNum比较,判断是否有下一页,进而判断是否去继续请求。
优点:
1、可以减少一定的DB压力。除了第一次外,其他请求只进行了一次IO操作。
缺点:
1、数据不及时。totalCount在查询过程期间可能会有变更。
优化二:
每次请求的时候,只根据pageNum和pageSize去请求数据,而不请求总记录数totalCount。当返回的记录个数小于pageSize的时候,说明没有更多记录,则说明没有下一页数据了。就不用再进行下页请求了。
优点:
1、减少了DB的压力,每次只进行一次IO操作。
2、数据实时更新,可以获取最新数据。
缺点:
1、不知道总记录数,不知道共多少页,管理系统平台一般都会要求显示总记录数、总页数不满足。
2、最后一页返回结果值恰好等于pageSize的时候,还要进行一次DB操作才知道没有下一页数据。
关于上面的缺点2,有另一种优化方式。
优化三
在优化二的基础上做一点改进,每次请求返回的数据量为pageSize+1。如果返回的结果数大于定义的pageSize,则说明还有下一页。则可以进行下一页请求。
优点:
1、改进了方案二中的最后一次DB无用请求。
缺点:
1、优化方案二中的缺点一依然存在。
2、每次多的数据需要处理,如果不处理会出现每一页的第一条和上一页的最后一条会出现重复,体验上有瑕疵。如果要处理还要在内存中做一下过滤,将最后一条过滤掉。增加了一定的逻辑复杂度。
好了,我所接触到的分页的基本原理,就以上这些方案。可根据具体场景以及系统容错读(CAP理论)选择合适的处理方案。
当然,大型系统中的分页远比我上文中介绍的要负责很多。在数据分库分表,以及服务器集群的情况下,以上的方案就会有一些问题了。至于这些情况,明天再述!