MongoDB分页查询优化方法
在网上看到很多关于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分页查询优化方法的更多相关文章
- MongoDB 分页查询的方法及性能
最近有点忙,本来有好多东西可以总结,Redis系列其实还应该有四.五.六...不过<Redis in Action>还没读完,等读完再来总结,不然太水,对不起读者. 自从上次Redis之后 ...
- C#MongoDB 分页查询的方法及性能
传统的SQL分页 传统的sql分页,所有的方案几乎是绕不开row_number的,对于需要各种排序,复杂查询的场景,row_number就是杀手锏.另外,针对现在的web很流行的poll/push加载 ...
- Mongodb 3 查询优化(语句优化、建索引)
一.explain(),语句分析工具 MongoDB 3.0之后,explain的返回与使用方法与之前版本有了很大的变化,介于3.0之后的优秀特色和我们目前所使用给的是3.0.7版本,本文仅针对Mon ...
- Mongoose 分页查询优化、获取数据总长度
无论是传统网页还是 ajax api,我们都不得不进行数据分页,一来节省带宽二来提升页面响应速度.作为一个数据完备的 web 应用,做好分页功能能极大提升用户体验. 简单的分页查询 在 mongoos ...
- MongoDB分页的Java实现和分页需求的思考
前言 传统关系数据库中都提供了基于row number的分页功能,切换MongoDB后,想要实现分页,则需要修改一下思路. 传统分页思路 假设一页大小为10条.则 //page 1 1-10 //pa ...
- [MongoDB]MongoDB分页显示
MongoDB Limit与Skip方法配合进行分页MongoDB Limit() 方法如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接 ...
- EF 分页查询优化
按照通常的方式分页查询至少要查询数据两遍,一个操作是查询总数,另一个是查询数据,这样有些耗时 这里介绍一个基于EF的插件 EntityFramework.Extended,当然这个插件有很多的功能,比 ...
- MongoDB中insert方法、update方法、save方法简单对比
MongoDB中insert方法.update方法.save方法简单对比 1.update方法 该方法用于更新数据,是对文档中的数据进行更新,改变则更新,没改变则不变. 2.insert方法 该方法用 ...
- 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% ...
随机推荐
- java8 运算语法集
1.分组并进行求和组合运算 示例主要代码: List<String> items = Arrays.asList("apple", "apple", ...
- 详解http报文(2)-web容器是如何解析http报文的
摘要 在详解http报文一文中,详细介绍了http报文的文本结构.那么作为服务端,web容器是如何解析http报文的呢?本文以jetty和undertow容器为例,来解析web容器是如何处理http报 ...
- FFmpeg(七)音频的播放
一.Open SL ES播放声音流程 简单说明 Open SL ES是android内部的接口,本身可以解码音频,但是我们用FFmpeg,,也可以来录音 . SL引擎:上下文 混音器:两路声音的混合 ...
- 【实战】 elasticsearch 写入速度提升的案例分享
文章首发投稿至InfoQ,[侠梦的开发笔记]公众号,欢迎关注 https://www.infoq.cn/article/t7b52mbzxqkwrrdpVqD2 基本配置 基本配置,5台配置为 24C ...
- Android实现apk插件方式换肤
换肤思路: 1.什么时候换肤? xml加载前换肤,如果xml加载后换肤,用户将会看见换肤之前的色彩,用户体验不好. 2.皮肤是什么? 皮肤就是apk,是一个资源包,包含了颜色.图片等. 3.什么样的控 ...
- python3 中的reload(sys)和sys.setdefaultencoding('utf-8')
通常我们为了防止出现乱码会进行一下操作 import sys reload(sys) sys.setdefaultencoding('utf-8') 但这是python2的写法,但是在python3中 ...
- 直通BAT面试题库锦集
01 python面试题(汇总) 02 面向对象 03 网络和并发编程 04 模块 05 设计模式 06 前端 07 Django框架 08 Flask 09 tornado 10 DB
- Xadmin查询
目录 深浅coopy运用 ModelForm的补充 提取模型当中相关属性 getattr和get_field的区别 __ str__,get_field,getattr初识 str ,当用getatt ...
- Redis 介绍学习
1.Redis 简介 Redis 是一个支持数据结构更多的键值对数据库.它的值不仅可以是字符串等基本数据 类型,也可以是类对象,更可以是 Set.List.计数器等高级的数据结构. Memcached ...
- Kotlin 中的伴生对象和静态成员
用了一段时间kotlin,越用越觉得好用,爱不释手啊,留点笔记. Kotlin 中,在类中定义的对象(object)声明,可使用 companion 修饰,这样此对象(object)就是伴生对象了.类 ...