一.索引详讲

索引是什么,索引就好比一本书的目录,当我们想找某一章节的时候,通过书籍的目录可以很快的找到,所以适当的加入索引可以提高我们查询的数据的速度。

准备工作,向MongoDB中插入20000条记录,没条记录都有number和name

> for(var i =  ; i< ;i++){
... db.books.insert({number:i,name:"book"+i})
... }
WriteResult({ "nInserted" : })
> db.books.find({},{_id:})
{ "number" : , "name" : "book0" }
{ "number" : , "name" : "book1" }
{ "number" : , "name" : "book2" }
{ "number" : , "name" : "book3" }
{ "number" : , "name" : "book4" }
{ "number" : , "name" : "book5" }
{ "number" : , "name" : "book6" }
{ "number" : , "name" : "book7" }
……
>

1.对比加入索引和不加入索引的查询效率

例:查询number为65535的name

不使用索引的情况下,查询时间请看millis

> db.books.find({number:},{_id:,name:}).explain()
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : ,
"nscannedObjects" : ,
"nscanned" : ,
"nscannedObjectsAllPlans" : ,
"nscannedAllPlans" : ,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : ,
"nChunkSkips" : ,
"millis" : ,
"server" : "G08FNSTD131598:27017",
"filterSet" : false
}
>

使用索引的情况下,先创建一个简单索引,用number建立一个索引

 db.books.ensureIndex({number:})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : ,
"numIndexesAfter" : ,
"ok" :
}
> db.books.find({number:},{_id:,name:}).explain()
{
"cursor" : "BtreeCursor number_1",
"isMultiKey" : false,
"n" : ,
"nscannedObjects" : ,
"nscanned" : ,
"nscannedObjectsAllPlans" : ,
"nscannedAllPlans" : ,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : ,
"nChunkSkips" : ,
"millis" : 0,
"indexBounds" : {
"number" : [
[
, ]
]
},
"server" : "G08FNSTD131598:27017",
"filterSet" : false
}
>

从上面可以看到,查询的时间上带索引的情况要有明显的缩短

2.从插入的数据的时间上进行对比

准备工作,删除刚刚建立的books文档

定义一个函数,来完成记录时间和插入数据的操作

> var time = function(){
... var start = new Date();
... for(var i = ;i < ; i++){
... db.books.insert({number:i,name:"book"+i});
... }
... var end = new Date();
... return end - start;
... }

不进行添加索引的时候:

> var x = time();
> x

创建索引

> db.books.ensureIndex({number:})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : ,
"numIndexesAfter" : ,
"ok" :
}

存在索引的时候的插入数据所用的时间

> var x = time();
> x

可以看到不存在索引的时候,插入的数据所用的时间较短

综上:当我们对一个文档需要进行频繁的插入操作的时候,建立不巧当的索引会导致插入效率的降低。

3.建立索引需要注意的地方

创建索引的时候注意1是正序创建索引-1是倒序创建索引

索引的创建在提高查询性能的同事会影响插入的性能

对于经常查询少插入的文档可以考虑用索引

符合索引要注意索引的先后顺序

每个键全建立索引不一定就能提高性能呢,索引不是万能的

在做排序工作的时候如果是超大数据量也可以考虑加上索引用来提高排序的性能

4.详细介绍索引的创建

①在创建索引的时候,使用了ensureIndex()这个方法,使用它会创建索引,名字就是键的名字加上一个数字,例如number_1或者number_-1,其中1代表是正序索引,-1代表逆序索引

②如果觉得1或-1比较不容易记,还可以使用自定义名字来创建索引

> db.books.ensureIndex({name:},{name:"bookNameIndex"})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : ,
"numIndexesAfter" : ,
"ok" :
}

③一个文档建立了多个索引,但是我又想强制使用其中的一个索引,怎么办

例如,我在上面的文档中对number建立了逆序索引,对name建立了正序索引,现在我想查找的时候用name进行索引,我应该这么写:

> db.books.find({name:"book2016"},{_id:}).hint({name:})
{ "number" : , "name" : "book2016" }
{ "number" : , "name" : "book2016" }
>

如果使用了没有创建的索引,那么会返回一个“bad hint”的错误。

④查看所用的索引和查询数据状态信息,可以使用explain()方法

> db.books.find({name:"book2016"},{_id:}).hint({name:}).explain()
{
"cursor" : "BtreeCursor bookNameIndex",
"isMultiKey" : false,
"n" : ,
"nscannedObjects" : ,
"nscanned" : ,
"nscannedObjectsAllPlans" : ,
"nscannedAllPlans" : ,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : ,
"nChunkSkips" : ,
"millis" : ,
"indexBounds" : {
"name" : [
[
"book2016",
"book2016"
]
]
},
"server" : "G08FNSTD131598:27017",
"filterSet" : false
}

上面看到,我们的索引的名字是bookNameIndex,并且millis是0,nscanned是查到了几个文档

⑤在关系型数据库中尝尝会有约束条件,比较常用的就是唯一性,在MongoDB中也可以指定唯一

建立唯一索引:db.books.ensureIndex({name:-1},{unique:true})

上面我通过有索引和无索引插入了两组完全一样的数据,此时如果去建立唯一的索引,那么就会出错

> db.books.ensureIndex({name:},{unique:true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : ,
"ok" : ,
"errmsg" : "E11000 duplicate key error index: mongoDBTest.books.$name_1
dup key: { : \"book0\" }",
"code" :
}

此时可以通过dropDups:true属性来进行删除重复的数据

> db.books.ensureIndex({name:},{unique:true,dropDups:true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : ,
"numIndexesAfter" : ,
"ok" :
}
>

删除重复之后,再去加入一个相同名字的数据,就会出现下面的情况

> db.books.insert({number:,name:"book1"})
WriteResult({
"nInserted" : ,
"writeError" : {
"code" : ,
"errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicat
e key error index: mongoDBTest.books.$name_1 dup key: { : \"book1\" }"
}
})
>

⑥删除索引

指定要删除的索引

db.runCommand({dropIndexes : ”books” , index:”name_-1”})

删除所有的索引

db.runCommand({dropIndexes : ”books” , index:”*”})

注意:索引的创建时同步的,所以如果想指定异步的去创建索引,就要指定在后台去创建

db.books.ensureIndex({name:-1},{background:true})

二.空间索引

2D索引,举例在一片区域中建立坐标系,那么很多地点可以看做是一个个的坐标,此时2d索引就可以帮助我们进行快速的查询某一个范围的地点了。

例:我在MongoDB中建立一个拥有很多坐标点的文档

> db.map.find({},{_id:})
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
>

1.添加一个2D索引

db.map.ensureIndex({"gis":"2d"},{min:-1,max:201})

默认会建立一个[-180,180]之间的2D索引

例子:

①查询点(70,180)最近的3个点

> db.map.find({"gis":{$near:[,]}},{gis:,_id:}).limit()
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }

②查询以点(50,50)和点(190,190)为对角线的正方形中的所有的点

> db.map.find({gis:{$within:{$box:[[,],[,]]}}},{_id:,gis:})
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
>

③查询出以圆心为(56,80)半径为50规则下的圆心面积中的点

> db.map.find({gis:{$within:{$center:[[,],]}}},{_id:,gis:})
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }
{ "gis" : { "x" : , "y" : } }

MongoDB的索引的更多相关文章

  1. MongoDB的索引(三)

    MongoDB的索引: 1. _id索引 该索引是大多数集合默认创建的索引,也就是说用户每插入一个数据,MongoDB会自动生成一条唯一的_id字段. 2. 单键索引 单键索引是最普通的索引,它不会自 ...

  2. MongoDB 覆盖索引查询

    MongoDB 覆盖索引查询 官方的MongoDB的文档中说明,覆盖查询是以下的查询: 所有的查询字段是索引的一部分 所有的查询返回字段在同一个索引中 由于所有出现在查询中的字段是索引的一部分, Mo ...

  3. MongoDB数据库索引

    前面的话 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录.这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查 ...

  4. MongoDB数据库索引构建情况分析

    前面的话 本文将详细介绍MongoDB数据库索引构建情况分析 概述 创建索引可以加快索引相关的查询,但是会增加磁盘空间的消耗,降低写入性能.这时,就需要评判当前索引的构建情况是否合理.有4种方法可以使 ...

  5. MongoDB索引(一) --- 入门篇:学习使用MongoDB数据库索引

    这个系列文章会分为两篇来写: 第一篇:入门篇,学习使用MongoDB数据库索引 第二篇:进阶篇,研究数据库索引原理--B/B+树的基本原理 1. 准备工作 在学习使用MongoDB数据库索引之前,有一 ...

  6. MongoDb进阶实践之七 MongoDB的索引入门

    一.引言     好久没有写东西了,MongoDB系列的文章也丢下好长时间了.今天终于有时间了,就写了一篇有关索引的文章.一说到"索引",用过关系型数据库的人都应该知道它是一个什么 ...

  7. 给MongoDB添加索引

    用过数据库的都知道,数据库索引与书籍的索引类似,都是用来帮助快速查找的.   MongoDB的索引跟关系型数据库的索引几乎一致.       1. 索引的创建   mongodb采用ensureInd ...

  8. linux环境给mongodb创建索引

    首先我们来了解索引,如果有基础的可以直接看最后面的操作. 可参照 DoNotStop 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/u013725455/artic ...

  9. MongoDB复合索引详解

    摘要: 对于MongoDB的多键查询,创建复合索引可以有效提高性能. 什么是复合索引? 复合索引,即Compound Index,指的是将多个键组合到一起创建索引,这样可以加速匹配多个键的查询.不妨通 ...

  10. 五、MongoDB的索引

    一.MongoDB的下载.安装与部署 二.MongoDB的基础知识简介 三.MongoDB的创建.更新和删除 四.MongoDB的查询 五.MongoDB的索引 1.简介 它就像是一本书的目录,如果没 ...

随机推荐

  1. asp.net Context.User.Identity.Name说明

    今天做了一个身份验证页面,基本实现功能,却不能显示当前用户姓名,自己MSDN半天一无所获,问题就在Context.User.Identity.Name:Context是HttpContext类,Use ...

  2. 约瑟夫环的java实现

    转自:http://www.cnblogs.com/timeng/p/3335162.html 约瑟夫环:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到 ...

  3. (转载)顺序栈c++实现

    (转载)http://myswirl.blog.163.com/blog/static/51318642200882310239324/ SqStack.h********************** ...

  4. Web---JS-返回上一页并刷新代码整理

    返回上一页并刷新在此功能有利于用户的体验,是每一个web开发人员所必备的一项,长话短说,今天介绍实现此功能的一个方法,需要了解的朋友可以参考下: 一:JS 重载页面,本地刷新,返回上一页 代码如下: ...

  5. CodeFirst-数据迁移-Migration

    http://www.cnblogs.com/haogj/archive/2012/02/17/2356537.html 1.安装最新NuGet 2.安装EntityFramework:在程序包管理器 ...

  6. bzoj 2618 2618: [Cqoi2006]凸多边形(半平面交)

    2618: [Cqoi2006]凸多边形 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 656  Solved: 340[Submit][Status] ...

  7. HTML5与CSS3权威指南.pdf3

    表单验证 <input name="text" type="text" required pattern="^\w.*$"> r ...

  8. JavaScript高级程序设计55.pdf

    输入模式 HTML5为文本字段新增了pattern属性,这个属性的值是一个正则表达式,用于匹配文本框中的值 例如,只想在允许在文本字段中输入数值 <input type="text&q ...

  9. 阐明iOS证书和provision文件

    译:阐明iOS证书和provision文件 许多iOS开发人员都会和你说在iOS开发很困惑的问题之一,将app真正运行在真实的设备(iPhone iPad而不是模拟器),因为所有的这些都会涉及从苹果获 ...

  10. VirtualBox安装Ghost XP

    http://jingyan.baidu.com/album/5d368d1e1a88b73f60c05721.html?picindex=1