一、简介

在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. weex-iOS集成

    weex-iOS集成 weex只是刚刚起步,还存在一些bug,有些功能还有待完善和提高.但是其使用起来还是可以节省些时间. 这里我们说说如何把weex集成到我们的iOS项目中 1. 下载weex源代码 ...

  2. mysql 求季度产量平均值

    表名:product 表结构: 表数据: 如果使用日期查询的话:sql: SELECT QUARTER(create_time) AS '季度',AVG(seller) AS '平均值' FROM p ...

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

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

  4. Tuning 07 Optimizing Sort Operations

  5. 第二百三十四节,Bootstrap表单和图片

    Bootstrap表单和图片 学习要点: 1.表单 2.图片 本节课我们主要学习一下 Bootstrap 表单和图片功能,通过内置的 CSS 定义,显示各 种丰富的效果. 一.表单 Bootstrap ...

  6. ASP.NET中JSON对时间进行序列化和反序列化

    JSON格式不直接支持日期和时间.DateTime值显示为“/Date(0+0800)/”形式的JSON字符串,其中第一个数字是GMT时区中自1970年1月1 日午夜以来按正常时间(非夏令时)经过的毫 ...

  7. EasyUI左右布居

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"><head runat=&quo ...

  8. 解决 Ubuntu 13.04 无法调节屏幕亮度的问题

    13.04与12.04大部分步骤是相同的,只是12.04的方法在13.04中失败了,所以还是有必要说明一下.我到电脑是宏碁AS4750G,硬盘安装系统后电源亮度无法调节. 解决方法如下: 终端输入代码 ...

  9. Github初试~从安装到连接到版本库

    这里我就只说说从安装到连接到github库时出现的错误,以及如何解决 1. 下载github,安装后你就可以在系统中右键看到 Gui 和 Bush按钮 2. 此时你可能会去尝试着去连接你在github ...

  10. Android中使用OnClickListener接口实现button点击的低级失误

    今天写了几行极为简单的代码,就是想implements  View.OnCLickListener.然后实现按钮点击操作.可是按钮却没有反应.找了五分钟还是没有结果. 下面是我的代码,希望大家不要嘲笑 ...