mongoDB之分页查询 skip() limit()

本文探讨了mongoDB在处理大量数据时的分页查询效率问题,指出内存消耗是关键因素。建议避免大容量skip操作,推荐采用多次少量查询,并通过time+_id进行排序优化。同时强调注意内存管理和查询效率,提供了解决方案和官方文档链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在研究 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));
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值