在网上看到很多关于MongoDB分页查询优化的文章,如出一辙。笔者自己实际生产中也遇到此问题,所以看了很多篇文章,这里分享一篇简明扼要的文章分享给大家,希望对大家在使用MongoDB时有所帮助。

凡事做过页面的,一般对分页不会陌生,也不会觉得它有多难:就是limit + offset的组合就可以了呀。但是,危险往往都是从最不起眼的地方开始的。在这里,我先说一下我之前在用MongoDB时遇到的问题。这类问题同样会出现在这种分页方式上。

当时,我需要对于MongoDB中的数据进行处理,每次处理一批,也相当于是按页来操作数据啦。这个没啥难度,直接使用API中的find + skip + limit就可以轻易搞定。迅速把程序写完之后就开始拿产品库开搞了。刚开始一切正常,可过了没多久,就发现整个程序的性能下降了。进入Mongo一查,发现是Table Scan。哇,那个collection中有上千万的数据啊!

此处略去3000字。

总之,问题最后解决了,程序又运行如飞。而解决之道很简单:只用find + limit,不再使用skip(原因自己想)。只不过在find中加了一个条件:上一批的最后一个document的_id。整个代码形似(groovy代码):

if (docId) {
batch = collection.find(['_id': ['$gt': docId]] as Document).limit(BATCH_SIZE)
} else {
batch = collection.find().limit(BATCH_SIZE)
}
docId = batch[-1]['_id']

  它的原理很简单,其实就是利用可以利用的index来加速分页。这种思想跟今天看到的文章的思路如出一辙,不再使用offset,寻找能达到同样效果的index,用它来助力搜索。因此,文中给出的方案跟上面的代码类似:

SELECT ...
FROM ...
WHERE ...
AND id < ?last_seen_id
ORDER BY id DESC
FETCH FIRST 10 ROWS ONLY

  

这种分页方式被称为“seek method”,其中的id被称为“seek predicate”。典型的seek predicate还可以是日期。需要提醒的是,seek predicate上需要有index才有意义,而且它可以有多列!采用这种方式的分页可以避免上述分页的潜在危险:当页数达到一定量之后,分页速度会严重下降。

MongoDB分页查询优化方法的更多相关文章

  1. MongoDB 分页查询的方法及性能

    最近有点忙,本来有好多东西可以总结,Redis系列其实还应该有四.五.六...不过<Redis in Action>还没读完,等读完再来总结,不然太水,对不起读者. 自从上次Redis之后 ...

  2. C#MongoDB 分页查询的方法及性能

    传统的SQL分页 传统的sql分页,所有的方案几乎是绕不开row_number的,对于需要各种排序,复杂查询的场景,row_number就是杀手锏.另外,针对现在的web很流行的poll/push加载 ...

  3. Mongodb 3 查询优化(语句优化、建索引)

    一.explain(),语句分析工具 MongoDB 3.0之后,explain的返回与使用方法与之前版本有了很大的变化,介于3.0之后的优秀特色和我们目前所使用给的是3.0.7版本,本文仅针对Mon ...

  4. Mongoose 分页查询优化、获取数据总长度

    无论是传统网页还是 ajax api,我们都不得不进行数据分页,一来节省带宽二来提升页面响应速度.作为一个数据完备的 web 应用,做好分页功能能极大提升用户体验. 简单的分页查询 在 mongoos ...

  5. MongoDB分页的Java实现和分页需求的思考

    前言 传统关系数据库中都提供了基于row number的分页功能,切换MongoDB后,想要实现分页,则需要修改一下思路. 传统分页思路 假设一页大小为10条.则 //page 1 1-10 //pa ...

  6. [MongoDB]MongoDB分页显示

    MongoDB Limit与Skip方法配合进行分页MongoDB Limit() 方法如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接 ...

  7. EF 分页查询优化

    按照通常的方式分页查询至少要查询数据两遍,一个操作是查询总数,另一个是查询数据,这样有些耗时 这里介绍一个基于EF的插件 EntityFramework.Extended,当然这个插件有很多的功能,比 ...

  8. MongoDB中insert方法、update方法、save方法简单对比

    MongoDB中insert方法.update方法.save方法简单对比 1.update方法 该方法用于更新数据,是对文档中的数据进行更新,改变则更新,没改变则不变. 2.insert方法 该方法用 ...

  9. jQuery EasyUI datagrid实现本地分页的方法

    http://www.codeweblog.com/jquery-easyui-datagrid%e5%ae%9e%e7%8e%b0%e6%9c%ac%e5%9c%b0%e5%88%86%e9%a1% ...

随机推荐

  1. 使用apache的poi来实现数据导出到excel的功能——方式一

    利用poi导出复杂样式的excel表格的实现. 我们要实现的效果是: 我们利用提前设计好模板样式,再在模板中填充数据的方式. 首先,pom.xml引入poi. <dependency> & ...

  2. Maven中jar包冲突的解决方式

    现象 创建一个maven工程,引入spring-context包. <dependency> <groupId>org.springframework</groupId& ...

  3. python win32com 读取带密码的excel

    之前用到的win32com读取带密码excel的相关内容,今天刚好准备整理下,突然发现方法又不灵了. 以下为错误示范: # 已知excel密码去除 def del_password(filename, ...

  4. CSS定位与布局

    我们在编写网页代码时,首先应该做的就是设计好页面的布局形式,然后再往里面填充内容.网页布局的好与坏,直接决定了网页最终的展示效果.PC端常见的网页布局形式有两列布局.三列布局等.在CSS中,我们通常使 ...

  5. [JavaScript] 《JavaScript高级程序设计》笔记

    1.||   和 && 这两个逻辑运算符和c#是类似的,都是惰性的计算 a() || b()  若a()为真返回a()的结果,此时b()不计算: a()为假则返回b() a() &am ...

  6. MongoDB 学习笔记之 权限管理基础

    权限管理基础 MongoDB有很多用户roles,这里只是简单列举下命令的使用,具体的role的含义,请查阅官方文档. https://docs.mongodb.com/manual/referenc ...

  7. 扛住阿里双十一高并发流量,Sentinel是怎么做到的?

    Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景 本文介绍阿里开源限流熔断方案Sentinel功能.原理.架构.快速入门以及相关框架比较 基本介绍 1 名词解释 服务限流 :当系 ...

  8. springboot结合mybatis

    idea中新建springboot项目 pom.xml依赖部分如下 <dependencies> <dependency> <groupId>org.springf ...

  9. SDN网络IPv6组播机制支持实时视频业务海量用户扩展

    以 OpenFlow 技术为核心的软件定义网络(SDN)框架具有集中控制的功能能够自己感知网络拓扑的变化,在细粒度的路径选择.接入控制.负载均衡方面有着天然的优势,为 IPv6 组播功能的实现提供了好 ...

  10. 数据存储检索之B+树和LSM-Tree

    作为一名应用系统开发人员,为什么要关注数据内部的存储和检索呢?首先,你不太可能从头开始实现一套自己的存储引擎,往往需要从众多现有的存储引擎中选择一个适合自己应用的存储引擎.因此,为了针对你特定的工作负 ...