MongoDB-6: MongoDB索引
一、简介
在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索引的更多相关文章
- MongoDB学习笔记~索引提高查询效率
回到目录 索引这个东西大家不会陌生,只要接触到稍微大一点的数据,都会用到这东西,它可以提升查询的速度,相当代价就是占用了更多的存储空间,这也是正常的,符合“能量守恒定理”,哈哈!今天说的是MongoD ...
- MongoDB学习笔记(索引)
一.索引基础: MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧.下面是创建索引的命令: > db.test.ensureIndex({" ...
- MongoDB的学习--索引
索引可以用来优化查询,而且在某些特定类型的查询中,索引是必不可少的.为集合选择合适的索引是提高性能的关键. 先来mock数据 for (i = 0; i < 1000000; i++) { db ...
- MongoDB学习笔记(索引)(转)
一.索引基础: MongoDB的索引几乎与传统的关系型数据库一模一样,这其中也包括一些基本的优化技巧.下面是创建索引的命令: > db.test.ensureIndex({" ...
- MongoDB学习笔记——索引管理
索引 索引能够提升查询的效率.没有索引,MongoDB必须扫描集合中的所有文档,才能找到匹配查询语句的文档. 索引是一种特殊的数据结构,将一小块数据集保存为容易遍历的形式.索引能够存储某种特殊字段或字 ...
- mongodb的地理位置索引
mongoDB支持二维空间索引,使用空间索引,mongoDB支持一种特殊查询,如某地图网站上可以查找离你最近的咖啡厅,银行等信息.这个使用mongoDB的空间索引结合特殊的查询方法很容易实现.前提条件 ...
- MongoDB的学习--索引类型和属性(转)
原文链接:MongoDB的学习--索引类型和属性 索引类型 MongDB的索引分为以下几种类型:单键索引.复合索引.多键索引.地理空间索引.全文本索引和哈希索引 单键索引(Single Field I ...
- 深入理解MongoDB的复合索引
更新时间:2018年03月26日 10:17:37 作者:Fundebug 我要评论 对于MongoDB的多键查询,创建复合索引可以有效提高性能.这篇文章主要给大家介绍了关于MongoDB复 ...
- MongoDB小结23 - 索引简介
MongoDB中的索引,可以看作是书的目录. 想象一下给你一本没有目录的书,然后让你去查询指定内容,我只想说,我不是电脑,我很蛋疼! 让你翻没有目录的书,就跟让电脑查询没有索引的集合一样,从头查询到尾 ...
- MongoDB数据模型和索引学习总结
MongoDB数据模型和索引学习总结 1. MongoDB数据模型: MongoDB数据存储结构: MongoDB针对文档(大文件採用GridFS协议)採用BSON(binary json,採用二进制 ...
随机推荐
- ping: icmp open socket: Operation not permitted 的解决办法
ping: icmp open socket: Operation not permitted 的解决办法:为ping加上suid即可.报错时ping的属性: [root@localhost ~]# ...
- redis源码学习_简单动态字符串
SDS相比传统C语言的字符串有以下好处: (1)空间预分配和惰性释放,这就可以减少内存重新分配的次数 (2)O(1)的时间复杂度获取字符串的长度 (3)二进制安全 主要总结一下sds.c和sds.h中 ...
- hMailServer之发送附件大小限制
hMailServer发送附件大小限制有以下几个地方: 1.php配置 参考 .post_max_size = 10M 表单提交最大数据为10M.此项不是限制上传单个文件的大小,而是针对整个表单的提交 ...
- nginx+tomcat多节点部署
在一台机器上想要将一个应用程序部署多个节点,可以通过nginx来实现. 1.将tomcat复制多份,修改tomcat配置文件conf/server.xml,将端口号设置成不一样的 2.将多个tomca ...
- IE下使用jquery失效的问题(转载)
1,然后各种调试,最后发现:把ie把关了,再打开$.get().会调用,再第二次调用的用的时候发现又不行了.于是我推断是ie缓存的问题,把ie缓存清除后,果然可以了.但是客户不可能知道清理缓存.所以只 ...
- ecmall的物流配送体系改造
接触多了ecshop.ecmall原始逻辑的,一般都习惯以整单的方式统一计算运费,这是一种很简单的思路. 但淘宝多了,就发现,物流运费没有那么简单. 首先,每种商品单独设置运费的体系,或者叫运费模板: ...
- 如何在Openwrt上,针对内核创建自定义Patch?
参考资料: 1.http://wiki.openwrt.org/doc/devel/patches?s[]=quilt --- 官方对于如何打Patch的说明 2.http://blog.csdn ...
- OSGI
OSGi(Open Service Gateway Initiative)技术是面向Java的动态模型系统.OSGi服务平台向Java提供服务,这些服务使Java成为软件集成和软件开发的首选环境.Ja ...
- Paxos发展、算法原理
Paxos 发展史 Leslie Lamport所提出的Paxos算法是现代分布式系统中的一项重要的基础性技术,得到广泛的应用. Paxos的整个发展过程大概可以分为三个阶段: 第一阶段:萌芽期,大致 ...
- Shell面试题8:筛选符合长度的单词案例
企业Shell面试题8:筛选符合长度的单词案例 利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题). I am oldboy teacher welcome to oldb ...