在研究 mongo 分页查询的过程中,发现数据量大了之后,就查询特别慢;在研究中发现,mongo 处理数据主要依赖内存,在 cpu,memory 的占用率过高的情况下,mongoDB 的效率就会直线下降;所以在对 mongo 操作的过程中,要注意内存的消耗;不可做任何占用大量内存的事情;
分页查询中,skip 数据量大了之后;效率就直线下降;
我们可以通过多次少量查询来解决这个问题,你会发现虽然查询多次,效率依然可观;
通过上次查询的结果作为下次查询的条件:
因为我由时间排序,所以我以时间为查询条件:
public static FindIterable<Document> findFindIterable(MongoCollection<Document> mongoCollection, BasicDBObject basicDBObject, Map<String, Integer> sort,String sortField, int skip, int limit, Date startTime, Date endTime) throws Exception{
if (mongoCollection == null) {
return null;
}
int sortNum = -1;
if (sort != null && StringUtils.isNotEmpty(sortField) && sort.get(sortField) != null) {
if (sort.get(sortField) == MongoEnums.Sort.ASC.getValue()) {
sortNum = 1;
}
}
int skipNum = 1600; //每次查询条数
int skipStart = 1600; //以此条数为起点
if (skip > skipStart) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
SimpleDateFormat sdfData = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
int f = (int)Math.floor(Double.valueOf(skip)/Double.valueOf(skipNum));
for (int i = 0; i <= f; i++) {
FindIterable<Document> findIterableSome = mongoCollection.find(basicDBObject).sort(new BasicDBObject(sortField,sortNum));
if (i<f) {
//查询获取时间
findIterableSome.limit(skipNum).skip(skipNum-1);
Document first = findIterableSome.first();
String date = first.get(sortField).toString();
date = sdf.format(sdfData.parse(date));
basicDBObject.remove(sortField);
if (sortNum == -1){
Map<String, Object> queryMap = new HashMap<String, Object>();
if (startTime != null) {
queryMap.put("$gt", startTime);
}
if (StringUtils.isNotEmpty(date)) {
Date end = sdf.parse(date);
queryMap.put("$lt", end);
}
basicDBObject.put(sortField, new BasicDBObject(queryMap));
} else {
Map<String, Object> queryMap = new HashMap<String, Object>();
if (StringUtils.isNotEmpty(date)) {
Date start = sdf.parse(date);
queryMap.put("$gt", start);
}
if (endTime != null) {
queryMap.put("$lt", endTime);
}
//重新设置时间条件
basicDBObject.put(sortField, new BasicDBObject(queryMap));