一、简介

在MongoDB建立索引能提高查询效率,只需要扫描索引只存储的这个集合的一小部分,并只把这小部分加载到内存中,效率大大的提高,如果没有建立索引,在查询时,MongoDB必须执行全表扫描,在数据量大时,效率差别就很明显,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。

索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构。索引项的排序支持高效的相等匹配和基于范围的查询操作。

从mongoDB 3.0开始ensureIndex被废弃,使用 createIndex创建索引。

创建索引的语法:

db.collection.createIndex(keys,options) 

参数

类型

描述

keys

document

一个包含该字段的字段和值对的文档,该文档的索引键和该值描述该字段的索引类型。对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为1。

MongoDB支持几种不同的索引类型,包括文本,空间,和哈希索引。查看更多信息的索引类型。

options

document

在创建索引的时的限制条件

二、 索引的基本操作

我们先插入10w条记录

for(var i=0;i<1000000;i++){
. db. orders.insert({
"onumber" : i,
"date" : "2015-07-02",
"cname" : "zcy"+i,
"items" :[ {
"ino" : i,
"quantity" : i,
"price" : 4.0
},{
"ino" : i+1,
"quantity" : i+1,
"price" : 6.0
}
]
})
}

1.      默认索引

存储在MongoDB集合中的每个文档(document)都有一个默认的主键“_id“,如果我们在添加新的文档时,没有指定“_id“值时,MongoDB会创建一个ObjectId值,并创建会自动创建一个索引在“_id“键上,默认索引的名称是”_id_“,并无法删除,如下面的命令查看:

>db.orders.getIndexes() 

2.       查看索引信息

返回一个数组,该数组保存标识和描述集合上现有索引的文档列表,可以查看我们是否有对某个集合创建索引,并创建哪些索引,方便我们管理。

语法:

>db.collection.getIndexes()  

3.      创建单列索引

我们对文档单个字段创建索引或者对内嵌文档的单个字段创建索引

语法:

db.collection.createIndex({field:boolean} }) 

boolean:对于某个领域的上升索引,指定一个值为1;对于下降的索引,指定一个值为-1。

(1)创建

例子:

db.orders.createIndex({cname:1})

我们对orders集合创建了cname索引,默认的索引名称是”cname_1“

 (2)根据条件查询文档,并查看查询效率怎么样

例子:

db.orders.find({"cname":"zcy100000"}) 

我们查询orders 集合根据条件cname为zcy100000的文档

我们测试有建索引和没建索引在1000000条文档执行查询的效率怎么样,我们这边先使用explain()函数,下一篇我们介绍

我们这边先介绍几个参数

1) n:当前查询返回的文档数量。

2)millis:当前查询所需时间,毫秒数。

3)indexBounds:当前查询具体使用的索引

例子:

db.orders.find({"cname":"zcy100000"}).explain()  

1)没建索引时,查询条件cname为zcy100000的文档

返回一个记录,花费1006毫秒,没使用到索引

2)有建索引,查询条件cname为zcy100000的文档

返回一个记录,花费82毫秒,有使用到cname索引

我们结果是相差很大的,有建索引字段,查询效率比较高,在大数据时,差别更明显。

(3)查询和排序组合使用

我们查询集合cname大于zcy100的文档并对onumber进行降序排序

例子:

db.orders.find({"cname":{$gt:"zcy1000"}}).sort({"onumber":1}).explain() 

执行出现错误:

"$err" : "Runner error:Overflow sort stage buffered data usage of 33554456 bytes exceeds internal limit of 33554432 bytes",

我们的内存只有33554432字节,对于包括一个没有索引的排序操作的查询,服务器必须在返回任何结果之前将所有的文档加载到内存中来进行排序。

我们对onumber创建索引

db.orders.createIndex({onumber:-1}) 

这次我们在执行时,可以正常执行,已经减少了内存的缓存的数据

4.       创建组合索引

我们可以同时对多个键创建组合索引

语法:

db.collection.createIndex({field1:boolean, field2:boolean } }) 

说明:

db.collection.createIndex({a:1,b:1,c:1 } })

我们对a、b、c进组合创建索引,支持查询时会用到索引的几种:

1)      a

2)      a,b

3)      a,b,c

这三中的查询条件,会使用到索引

(1)      创建组合索引

我们同时对onumber和cname进行组合索引

例子:

>db.orders.createIndex({cname:1,onumber:-1})  

索引存储在一个易于遍历读取的数据集合中,存储的数据

{_id:..,"onumber" : 2, "date" : "2015-07-02", "cname" : "zcy1"})

{_id:..,"onumber" : 1, "date" : "2015-07-02", "cname" : "zcy1"})

{_id:..,"onumber" : 1, "date" : "2015-07-02", "cname" : "zcy2"})

(2) 查询

1)我们对cname和onumber作为查询条件时

例子:

>db.orders.find({"cname":{$gt:"zcy1000"},"onumber":2000}).explain() 

我们查询条件cname大于zcy1000并且onumber等于2000的数据,我们用explain()查询索引使用情况

2)我们只用两个索引其中一个作为查询时

第一种情况:我们条件只使用"cname":{$gt:"zcy1000"}作为查询条件

例子:

>db.orders.find({"cname":{$gt:"zcy1000"}}).explain()

会使用到索引,符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到索引的第一种。

第二种情况:我们条件只使用"onumber":2000作为查询条件

例子:

> db.orders.find({"onumber":2000}).explain() 

不会使用到索引,不符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到几种。

(3)查询和排序组合使用

我们查询集合cname大于zcy100的文档并对onumber进行降序排序

例子:

    >db.orders.find({"cname":{$gt:"zcy1000"}}).sort({"onumber":1}).explain()  

执行出现错误:

"$err" : "Runner error:Overflow sort stage buffered data usage of 33554456 bytes exceeds internal limit of 33554432 bytes",

sort时,不会使用到索引,不符合我们前面介绍的我们对a、b、c进组合创建索引,支持查询时会用到几种。

总结:我们在使用组合索引时,查询时会用到组合索引的前端的几种组合。

我们对a、b、c进组合创建索引,支持查询时会用到索引的几种:

1)      a

2)      a,b

3)      a,b,c

5.      内嵌文档的索引

我们对内嵌文档创建索引时,跟基本文档创建索引一样

语法:

db.collection.createIndex({field:boolean} })  

field说明:以“.“来指明内嵌文档的路径

(1)      单列的内嵌文档的索引创建

例子:

    >db.orders.createIndex({"items.info":1})  

我们orders集合下的内嵌items集合的info字段创建索引

我们以items.info字段作为查询条件,并使用索引的情况

例子:

db.orders.find({"items.info":{$lt:100}}).explain() 

我们查询items.info小于100的数据

 (2)      组合的内嵌文档的索引的创建

我们对内嵌文档创建组合索引时,跟基本文档创建组合索引一样

语法:

>db.collection.createIndex({field1:boolean, field2:boolean } })  

例子:

>db.orders.createIndex({"items.info":1, "items. quantity":-1}) 

6.      删除索引

我们对已经创建的索引进行删除,可以针对具体的集合中索引进行删除,也可以对所有的集合中的所有索引删除

(1)具体索引名称删除索引

语法:

db.collection.dropIndex(index) 

删除具体的索引,根据索引名称删除,如果不知道索引的名称,可以通过db.collection.getIndexes()查看索引名称

例子:

    > db.orders.dropIndex("cname_1")  

我们删除cname字段的索引,现在只剩下onumber字段索引

 (2)删除集合中所有索引

语法:

db.collection.dropIndexes()  

例子:

> db.orders.dropIndexes() 

我们对集合中的索引都删除,我们删除cname字段的索引和onumber字段索引,现在只剩默认的_id字段索引,索引我们在使用时,要谨慎,以免把集合中的索引都删除。

  (3)对dropIndexes方法,我们还有一种用法,可以指定集合的具体索引的删除

例子:

    > db.runCommand({"dropIndexes":"orders","index":"cname_1"})  

我们删除cname字段的索引,现在只剩下onumber字段索引

总结:

在MongoDB建立索引能提高查询效率,但在MongoDB新增、修改效率上比较慢

MongoDB-6: MongoDB索引的更多相关文章

  1. MongoDB学习笔记~索引提高查询效率

    回到目录 索引这个东西大家不会陌生,只要接触到稍微大一点的数据,都会用到这东西,它可以提升查询的速度,相当代价就是占用了更多的存储空间,这也是正常的,符合“能量守恒定理”,哈哈!今天说的是MongoD ...

  2. MongoDB学习笔记(索引)

    一.索引基础:    MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧.下面是创建索引的命令:    > db.test.ensureIndex({" ...

  3. MongoDB的学习--索引

    索引可以用来优化查询,而且在某些特定类型的查询中,索引是必不可少的.为集合选择合适的索引是提高性能的关键. 先来mock数据 for (i = 0; i < 1000000; i++) { db ...

  4. MongoDB学习笔记(索引)(转)

    一.索引基础:    MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧.下面是创建索引的命令:    > db.test.ensureIndex({" ...

  5. MongoDB学习笔记——索引管理

    索引 索引能够提升查询的效率.没有索引,MongoDB必须扫描集合中的所有文档,才能找到匹配查询语句的文档. 索引是一种特殊的数据结构,将一小块数据集保存为容易遍历的形式.索引能够存储某种特殊字段或字 ...

  6. mongodb的地理位置索引

    mongoDB支持二维空间索引,使用空间索引,mongoDB支持一种特殊查询,如某地图网站上可以查找离你最近的咖啡厅,银行等信息.这个使用mongoDB的空间索引结合特殊的查询方法很容易实现.前提条件 ...

  7. MongoDB的学习--索引类型和属性(转)

    原文链接:MongoDB的学习--索引类型和属性 索引类型 MongDB的索引分为以下几种类型:单键索引.复合索引.多键索引.地理空间索引.全文本索引和哈希索引 单键索引(Single Field I ...

  8. 深入理解MongoDB的复合索引

    更新时间:2018年03月26日 10:17:37   作者:Fundebug    我要评论 对于MongoDB的多键查询,创建复合索引可以有效提高性能.这篇文章主要给大家介绍了关于MongoDB复 ...

  9. MongoDB小结23 - 索引简介

    MongoDB中的索引,可以看作是书的目录. 想象一下给你一本没有目录的书,然后让你去查询指定内容,我只想说,我不是电脑,我很蛋疼! 让你翻没有目录的书,就跟让电脑查询没有索引的集合一样,从头查询到尾 ...

  10. MongoDB数据模型和索引学习总结

    MongoDB数据模型和索引学习总结 1. MongoDB数据模型: MongoDB数据存储结构: MongoDB针对文档(大文件採用GridFS协议)採用BSON(binary json,採用二进制 ...

随机推荐

  1. JDK的动态代理机制

    JDK Proxy OverView jdk的动态代理是基于接口的,必须实现了某一个或多个随意接口才干够被代理,并且仅仅有这些接口中的方法会被代理.看了一下jdk带的动态代理api.发现没有样例实在是 ...

  2. Unable to verify your data submission错误解决

    如果不用Yii2提供的ActiveForm组件生成表单,而是自定义表单,那么当你提交表单的时候就会报这个错误 Unable to verify your data submission 这是因为Web ...

  3. Oracle之函数concat、lpad

    一.引言 程序测试需要生成大量的测试数据,且测试数据有主键,主键自增,于是决定用存储过程来实现,经过半天的查资料终于完成了,记录之,学习之 二.存储过程 格式: CREATE PROCEDURE re ...

  4. [转]c++ 为什么要将基类的析构函数声明为Virtual?

    http://www.cnblogs.com/alephsoul-alephsoul/archive/2012/10/12/2721410.html

  5. JAVA设置HttpOnly Cookies

    HttpOnly Cookies是一个cookie安全行的解决方案. 在支持HttpOnly cookies的浏览器中(IE6+,FF3.0+),如果在Cookie中设置了"HttpOnly ...

  6. java部署ubuntu后中文显示问号问题

    1.首先先回忆自身项目的编码格式,即在本地进行编码时使用的编码格式.UTF-82.检测tomcat的设置问题,在web.xml和server中的设置:server.xml中: <Connecto ...

  7. 从以下哪一个选项中可以获得Servlet的初始化参数。

    从以下哪一个选项中可以获得Servlet的初始化参数. A.Servlet B.ServletContext C.ServletConfig D.GenericServlet 解答:C servlet ...

  8. easyreport 安装手记

    jdk tomcat eclipse maven 按下不表,网上多了去,将遇到的几个坑回顾下: 1.要安装lombok.jar 详见 https://www.cnblogs.com/lrzy/p/10 ...

  9. 【BZOJ】1026: [SCOI2009]windy数(数位dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1026 我果然很弱啊... 考虑数位dp.枚举每一位,然后限制下一位即可. 一定要注意啊!在dfs的时 ...

  10. jni调用 java.lang.UnsatisfiedLinkError: no segmentor_jni in java.library.path

    改过 LD_LIBRARY_PATH 改过 /etc/ld.so.conf 参考这篇文章 http://blog.csdn.net/zjuylok/article/details/4152559 最后 ...