一.索引详讲

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

准备工作,向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. BZOJ2802: [Poi2012]Warehouse Store

    2802: [Poi2012]Warehouse Store Time Limit: 10 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 121  ...

  2. 日常工作中使用的一些Mongodb语句

    .通过_userID字段查询重复录入内容 > db.template.aggregate({}}},{$}}) .查询 db.template.find({"group_7ee1247 ...

  3. HDU-2548 两军交锋

    两军交锋 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  4. HTTP 500 - 内部服务器错误

    问题1 问:当调试程序出错的时候,为什么有的机器总是出现“HTTP 错误 500.100 - 内部服务器错误 - ASP 错误”,而不能显示具体的出错信息? 原因: IE浏览器设置中屏蔽掉了出错的具体 ...

  5. python 默认的系统编码 sys.setdefaultencoding

    python2.x的编码问题有时让人很头疼,一会ascii,一会unicode. 在脚本里多见这样的操作: import sys reload(sys) sys.setdefaultencoding( ...

  6. HDOJ 1004题 Let the Balloon Rise strcmp()函数

    Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...

  7. (DT系列二)device tree的书写规范

    devicetree的书写规范 下面从节点,属性,reg,ranges,中断控制器等几个方面叙述devicetree的书写规范. 1,dts的基本元素:节点 .dts(或者其include的.dtsi ...

  8. 排列的Java递归语言实现

    在做算法题的时候,发现排列经常被使用到,是一个重要的知识点, 下面是博主修改过的代码,初学者,如有不足,欢迎指出 import java.util.ArrayList; import java.uti ...

  9. hdoj 1047 Integer Inquiry

    Integer Inquiry Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  10. typeahead使用配置参数。

    示例代码: var suggestion_source = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace( ...