问题
在Java中使用mongodb的MongoTemplate进行分页时,一般的策略是使用skip+limit的方式,但是这种方式在需要略过大量数据的时候就显得很低效(即skip趋向于变大)。
而且, 在数据查询语句中使用到了SORT排序的时候,mongo很容易内存溢出,报出如下错误:
lan executor error during find: Overflow sort stage buffered data usage of 33568573 bytes exceeds internal limit of 33554432 bytes
sort会将当前搜索出来的数据放入缓存,进行排序,如果一次性查询的输出量太大,超过33554432bytes,即报内存溢出异常
这种情况下要么去掉sort,要么减少一次性查询的输出量。
但是,sort是业务需求,能做的优化就是从一次性查询的输出量上想办法。
方法
目前我实践的有两种分页方法:
一、将上一页最后一条数据的时间戳作为搜索条件。这样做有一个局限,只能在连续跳页中使用,如果是间断式跳页,就无法满足。
二、如果skip略过量超过5000条,将搜索结果按5000条进行第一层分页,每次获取5000条数据中的最后一条数据的时间戳,用作下一次的查询条件,每次循环skip略过量就减少5000,循环直至skip少于5000条,然后再skip,代码如下:
int pageSkip = 5000;
if(s.getOffset()>pageSkip){
i