zoukankan      html  css  js  c++  java
  • mongodb分页优化

    现在参与一个项目的开发,需要用java查询mongodb数据库,在这里分页用的skip sort 和limit结合,查询语句如下(已经在相关字段建立索引)

    DBCursor cursor = collection.find(query).skip((skip - 1) * PAGESIZE).sort(new BasicDBObject("starttime", -1)).limit(PAGESIZE);//PAGESIZE=10


    由于分页,这里需获取符合条件的总数 语句如下

    int count = cursor.count()

    根据count和PAGESIZE的两个数据来分页。由于带条件的count()方法执行起来特别耗时,我用二百万的数据测试了一下,cursor.count()就耗时6.5s多,mongodb权威指南这不书也指出count()方法随着查询条件越多,执行速度越慢。

    现在问题出来了,现在模拟一下操作

    1)点击查询执行查询方法queryLists()(这是我代码中的方法名)并执行耗时的count()方法获取符合条件的数量,进行分页

    2)点击下一页或者点击某一页时,同样执行queryLists()方法,同样也需要执行该方法体中的count()方法,这样count方法又耗去一部分时间

    显然用户体验不是很好,每次点击查询时就很耗时了,点击下一页或者某一页时同样还得等待,这样的话谁都受不了


    下面是我的优化方案

    1)设置一个变量clickQuery,当用户点击查询按钮时 clickQuer赋值为0.当点击下一页或者上一页或者跳转页面时clickQuery=1.

         也就是说用clickQuery来判断用户是否点击查询按钮

    2)既然点击查询时已经获取了count,何必再点击下一页时在执行cursor.count()方法呢?所以我的做法就是把点击查询的时候获取的count保存起来

        当用户点击下一页的时候,直接读取已经保存的count,而不是执行耗时的cursor.count()方法


    方法优点:

          点击下一页或者某一页或者跳转页面时,由于已经保存过查询时的count,所以速度很快

    方法缺点:

        用户点击查询按钮时,因为要执行cursor.count方法,所以还是很慢。


    代码实现如下

    int count = 0;
    if (click.equals("0")) {// 如果点击查询
        count = cursor.count();//获取符合条件的数量
        // 序列化,保存count2
       Seria.serializable(new BtnClick(count), Seria.ACTIVITY_COUNT_FILE);
       System.out.println("点击查询");//Seria是我自己定义的一个类,来序列化数据
    } else {// 如果点击下一页或者跳转页
      // 读取序列化信息
      BtnClick btnClick = Seria.reverseSer(Seria.ACTIVITY_COUNT_FILE);
      count= btnClick.getCount();
       System.out.println("点击下一页");
    }
    ///分页处理略
    


    	/**
    	 * 序列化
    	 */
    	public static void serializable(BtnClick btnClick,String file) {
    		try {
    			
    			File serFile = new File(file);
    			// 判断序列化文件是否存在, 不存在则创建
    			if (!serFile.exists())
    				serFile.createNewFile();
    			//打开serFile的输出流
    			FileOutputStream fos = new FileOutputStream(serFile);
    			ObjectOutputStream oos = new ObjectOutputStream(fos);
    			// 将上下文对象写到序列化文件中
    			oos.writeObject(btnClick);
    			oos.close();
    			fos.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 反序列化
    	 */
    	public static BtnClick reverseSer(String file) {
    		File serFile = new File(file);
    		BtnClick btnClick = null;
    		if (!serFile.exists())
    			return null;
    		try {
    			// 得到文件输入流
    			FileInputStream fis = new FileInputStream(serFile);
    			ObjectInputStream ois = new ObjectInputStream(fis);
    			// 设置ContextHolder的DownloadContext
    		    btnClick = (BtnClick) ois.readObject();
    			ois.close();
    			fis.close();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	
    		return btnClick;
    	}


    我的问题:因为用skip方法查询大量数据的时候速度慢,不知道有什么方法可以优化一下,mongodb权威指南的那个方法,只适合一页一页的调整而不适合跨页跳转,所以大家如果有好的查询方案,可以和小弟在此说一下,谢谢。

    同样以上方法如有不当之处,欢迎批评指正

     

  • 相关阅读:
    Java基本数据类型学习
    【异常】Docker安装elasticsearch7, 浏览使用 9200 无法打开
    docker logs-查看docker容器日志
    centos开开放防火墙
    软工超越日报-android的简单旋转效果实现 5/13
    软工超越日报-Android文件下载器 5/12
    软工超越日报-团队第一阶段冲刺十日谈回顾总结 5/11
    软工超越日报-安卓APP联网获取数据(3) 5/10
    软工超越日报-安卓APP联网获取数据(2) 5/9
    软工超越日报-安卓APP联网下载数据(1) 5/8
  • 原文地址:https://www.cnblogs.com/riskyer/p/3303954.html
Copyright © 2011-2022 走看看