mongDB 分页优化
来源:互联网 发布:python configobj 编辑:程序博客网 时间:2024/05/17 22:57
具体到这次调优,是一个关于mongoDB的分页问题。在分页时如果用skip,在页数比较大时,性能下降得非常厉害。
具体语句是db.foo.find().sort().skip().limit();mongo官方也明确说不建议用skip做分页。
做分页的标准做法是,记住上一个页的最后一个值,然后取这个值之后的100条记录,这样回避skip。具体语句如下:
var latest = null;
//显示第一页
while(page1.hasNext()) {
latest = page1.next(); //记住当前对象,在循环结束时,这个对象就是这页的最后一个对象
display(latest); //送到前台展示
}
// 获取下一页,假设表名是foo,按date进行排序,$gt是大于的意思
var page2 = db.foo.find({"date":{"$gt":latest.date}}); //取时间大于latest.date的数据
page2.sort({"date":-1}).limit(100); //在游标page2中取头100行记录。
这样就避免使用skip了。这是标准做法。
但即使这样的做法,数据量特别大时,性能也不好,尤其是用户直接点取最后一页时。
我建议在最后几页时,采用和取头几页相反的顺序。例如正常取评论时,是按时间逆序的,如果用户要看最后一页,就按时间正序取数据就好了,当然具体到产品,还有一些条件分支什么的,这些是宝龙自己细化的。
这种与正常逆序的取法,实际不是我自己想出来的,网上有一篇关于mongo调优的博文,最后一段提到了这种做法。
博文网址:http://blog.nosqlfan.com/html/3760.html
很好的一篇文章。
案例
//统计img public List<VideoEncode> doStaticImg() { List<VideoEncode> list = new ArrayList<VideoEncode>(); int pageSize = 100; long count = videoEncodeDao.getCount(startTime, endTime); long pageCount = count % pageSize == 0 ? count / pageSize : count / pageSize + 1; long createTime = startTime; for (int i = 0; i < pageCount; i++) { List<VideoEncode> videoEncodeList = videoEncodeDao.getAll(createTime, endTime, pageSize); if (videoEncodeList.isEmpty()) break; createTime = videoEncodeList.get(videoEncodeList.size()-1).getCreateTime(); List<VideoEncode> imgFailList = getImgPathFail(videoEncodeList); if (!imgFailList.isEmpty()) list.addAll(imgFailList); } return list; }
//获取指定时间转码、分发,checksum完成的任务 public List<VideoEncode> getAll(long startTime, long endTime,int count){ Query <VideoEncode> query=createQuery(); query.field("status").equal(VideoEncode.STATUS_COMPLETE).field("videoCDNStatus").equal(VideoEncode.CDN_STAUTS_COMPLETE); query.field("checksumStatus").equal(VideoEncode.CDN_STAUTS_COMPLETE).field("mmsStatus").equal(VideoEncode.MMS_STATUS_SYNCED); query.field("vtype").equal("1").field("createTime").greaterThan(startTime).field("createTime").lessThan(endTime).order("encodeId"); query.limit(count); QueryResults <VideoEncode> queryResults=find(query); return queryResults.asList(); }//获取指定时间转码、分发,checksum完成的任务数量 public long getCount(long startTime, long endTime){ Query <VideoEncode> query=createQuery(); query.field("status").equal(VideoEncode.STATUS_COMPLETE).field("videoCDNStatus").equal(VideoEncode.CDN_STAUTS_COMPLETE); query.field("checksumStatus").equal(VideoEncode.CDN_STAUTS_COMPLETE).field("mmsStatus").equal(VideoEncode.MMS_STATUS_SYNCED); query.field("vtype").equal("1").field("createTime").greaterThan(startTime).field("createTime").lessThan(endTime); return count(query); }
- mongDB 分页优化
- MongDB分页java实现
- mongdb索引查询优化
- mongdb性能优化收集
- mongdb性能优化收集
- mongdb模糊查询与分页
- mongdb
- mongdb
- MongDB
- Mongdb
- mongdb
- mongdb
- 分页优化
- MongDB基础学习(五)——投影,分页,排序,聚合
- java操作mongdb多条件复合查询(包括模糊查询和按时间段查询),分页
- MongDB基础学习(五)——投影,分页,排序,聚合
- 查询优化和分页
- 查询优化和分页
- Java动态代理学习2——静态代理和动态代理并对照spring的通知
- 分段函数
- jquery ajax return没有返回值的解决方法,需要的朋友可以参考下。
- 关于Qualcomm 的MSM7X & MSM8XI2C驱动分析
- ssh免密码设置
- mongDB 分页优化
- Java中的回调
- SYSLOG&滚动日志
- 二叉树的建立与遍历
- Android CMWAP和CMNET 切换APN
- HOJ 2089 4th point
- url编码
- BinaryFormatter 的简单使用
- linux-C实现查看目录中所有文件