常用性能优化方案

创建索引

限定返回结果数

只查询使用到的字段

采用capped collection

采用Server Side Code Execution

使用Hint,强制使用索引

Hint

虽然MongoDB查询优化器一般工作的很不错,但是也可以使用hint()来强迫MongoDB使用一个特定的索引。在这种方法下某些情形下会提升性能。一个有索引的collection并且执行一个多字段的查询。传入一个制定的索引,强迫查询使用该索引。

db.users.find({"username":"user1000", "age":30}).hint({"username":1})

注意:请确定你已经创建了相应的索引。

假设在users上有个{"a": 1, "b": 1}的索引,名称是"a_1_b_1",则如下两种方式等价:

db.users.find({"a": 4, "b": 5, "c": 6}).hint({"a": 1, "b": 1})
db.users.find({"a": 4, "b": 5, "c": 6}).hint("a_1_b_1")

也可以强迫查询不适用索引,做表扫描:

db.users.find().hint({"$natural":1})

采用Profiling

其他优化

1、MongoDB中低效率的操作符

"$where"和"$exists":这两个操作符,完全不能使用索引。

"$ne":通常来说取反的效率比较低。"$ne"查询可以使用索引,但并不是很有效。因为他必须查看所有的索引条目,而不是"$ne"指定的条目,这个时候他就不得不扫描整个索引。

"$not":有时候能够使用索引,但是他通常并不知道要如何使用索引。所以大多数情况"$not"会退化为全表扫描。

"$nin":这个操作符总是会全表扫描

2、OR查询

MongoDB在一次查询中只能使用一个索引(至少我现在用的2.6是这样的),如果你在{"x":1}上有一个索引,在{"y":1}上也有一个索引,在{"x":1,"y":1}上执行查询时,MongoDB只会使用其中一个索引,而不是两个一起使用。"$or"是一个例外,"$or"可以对每个字句都使用索引,因为"$or"实际上是执行两次查询然后将结果合并。

通常来说,使用or查询多次在合并结果,不如单次查询的效率高,对于单个字段,应该尽可能使用$in。

3、MongoDB的查询优化器

MongoDB的查询优化器与其他数据库的稍微不同。基本来说,如果一个索引能够精确匹配一个查询,那么查询优化器就会使用这个索引,如果不能精确匹配,可能会有几个索引都适合你的查询。那MongoDB是怎样选择的呢?答:MongoDB的查询计划会将多个索引并行的去执行,最早返回100个结果的就是胜者,其他查询计划都会被终止。

这个查询计划会被缓冲,接下来的这个查询都会使用他,下面几种情况会重新计划;

    1. 最初的计划评估之后集合发生了比较大的数据波动,查询优化器就会重新挑选可行的查询计划。
    2. 建立索引时。
    3. 每执行1000次查询之后,查询优化器就会重新评估查询计划

4、何时不应该使用索引

提取较小的子数据集时,索引非常有效(所以才有了分页)。也有一些查询不使用索引会更快。结果集在原集合中所占的比例越大,查询效率越慢。因为使用索引需要进行两次查找:一次查找索引条目,一次根据索引指针去查找相应的文档。而全表扫描只需要进行一次查询。在最坏的情况,使用索引进行查找次数会是全表扫描的两倍。效率会明显比全表扫描低。

可惜并没有一个严格的规则可以告诉我们,如果根据索引大小、文档大小来判断什么时候索引很有用,一般来说,如果查询需要返回集合内30%的文档(或者更多),那就应该测试全表扫描和走索引查询那个速度比较快。这个数字也会在2%~60%之间进行波动。

这个时候可以使用hint({"$natural":true})强制查询走全表扫描。

IT版孔乙己(转)的更多相关文章

  1. FreeBSD 乃至开源界中的孔乙己 再论苦难哲学之一

    在许多狂热的FreeBSD 粉丝里,他们甚至不允许别人把FreeBSD写作freebsd,要和你强调,F和BSD都是大写的.还说这是什么尊重之类的东西.大抵和孔乙己的茴香豆的茴的有四种写法一样吧:&q ...

  2. 孔乙己,一名ERP顾问

    欢迎关注微信公众号:sap_gui (ERP咨询顾问之家) 公司的会议室的格局,是和别处不同的:都是中间一个大的会议圆桌,桌子上面放着各台电脑,可以随时打开ERP系统.做ERP顾问的人,傍午傍晚下了班 ...

  3. 夕甲甲——孔乙己之C++版

    欧欧匹代码的格局,是和别的编程模式不同的:首先要有一个构造函数:基类里只定义了函数的形式,可以随时通过派生增加不同的实现.那些程序员们,每每学会了继承和多态,便可以接一个项目,——这是十年前的事,现在 ...

  4. 转 夕甲甲:孔乙己之 C++ 版

    欧欧匹代码的格局,是和别的编程模式不同的:首先要有一个构造函数:基类里只定义了函数的形式,可以随时通过派生增加不同的实现.那些程序员们,每每学会了继承和多态,便可以接一个项目,——这是十年前的事,现在 ...

  5. “Python的单例模式有四种写法,你知道么?”——孔乙己

    什么是单例模式 单例模式(Singleton Pattern)是最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创建自己的 ...

  6. 我曾做过陈士成,也做过孔乙己,还做过阿Q

    一. 我现在是陈士成,陈士成现在是我.为什么这么说呢? 那年那天,天刚微微亮,似乎还在打着哈欠.我和父亲去得很早,为的就是在“小升初的考试成绩榜单”前面占一个有利的位置.我不记得当时穿的厚还是不厚,体 ...

  7. 哈希表的C实现(三)---传说中的暴雪版

    关于哈希表C实现,写了两篇学习笔记,不过似乎网上流传最具传奇色彩的莫过于暴雪公司的魔兽文件打包管理器里的hashTable的实现了:在冲突方面的处理方面,采用线性探测再散列.在添加和查找过程中进行了三 ...

  8. [php][thinkphp] 记一次Composer Linux版安装以及用它进行thinkphp项目初始化

    Composer安装thinkphp,thinkphp5.1开始官网不在提供下载包,只能通过git clone 和Composer包管理器进行下载. php中开启exec,system等函数调用系统命 ...

  9. 一篇关于学C++的感想(拿来与大家分享)

    学计算机的如果你有耐心看下去,我敢保证这绝对是一种收获 期待爱 大师提醒: 计算机专业不是学编程,而是懂得计算机的工作原理,以及和计算机相关的学科技术.一个高手不必懂得编程,coder是最底层的人物, ...

随机推荐

  1. [2-sat]HDOJ3622 Bomb Game

    题意:给n对炸弹,每对炸弹选其中一个爆炸. 每个炸弹爆炸的半径相同 圆不能相交, 求最大半径 2-sat简介 二分半径, 枚举n*2个炸弹 若i炸弹与j炸弹的距离小于半径*2 则建边 比如  第一对炸 ...

  2. Perl 三种时间time,localtime,gmttime

    #!/usr/bin/perl use warnings; use diagnostics; use strict; use POSIX; print "time: ", time ...

  3. 李洪强iOS开发之OC[014] -对象的存储细节

    // //  main.m //  13 - 对象的存储细节 // //  Created by vic fan on 16/7/9. //  Copyright © 2016年 李洪强. All r ...

  4. lintcode:数飞机

    数飞机 给出飞机的起飞和降落时间的列表,用 interval 序列表示. 请计算出天上同时最多有多少架飞机? 如果多架飞机降落和起飞在同一时刻,我们认为降落有优先权. 样例 对于每架飞机的起降时间列表 ...

  5. *EditPlus注册码在线生成

    http://www.jb51.net/tools/editplus/

  6. 4、处理方法中获取请求参数、请求头、Cookie及原生的servlet API等

    1.请求参数和请求头 使用@RequestParam绑定请求参数,在处理方法的入参处使用该注解可以把请求参数传递给请求方法 —— value :参数名 —— required : 是否必须,默认为tr ...

  7. Mysql:常用代码

    C/S: Client Server B/S: Brower Server Php主要实现B/S .net IIS Jave TomCat LAMP:L Mysql:常用代码 Create table ...

  8. Xml文件保存值不能及时更新

    今天在Xml文件中修改了一个值,调试时,发现读取的不是最新值.经过各种调试,还是不能解决.只好把文件项目给编译了一遍,在调试时,把在及时窗口,把变量值给改了一下啊,就是可以读到最新配置了.停止程序,在 ...

  9. Android开发之通过反射获取到挂断电话的API

    Android开发黑名单工具类,需要用到挂断电话的API,但是该API处于隐藏状态,需要通过反射得到该方法.. 步骤: 1.通过当前类获取到ServiceManager的字节码 Class< ? ...

  10. JEE学习线路

    传智播客:javaEE学习线路以及需要掌握的知识点:http://java.itcast.cn/subject/javastudypath/index.shtml 最近在学JavaEE,没学Java ...