一.索引详讲

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

准备工作,向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. MySQL 备份表和数据

    方法1: Create table new_table_name (Select * from old_table_name); 方法2: 1.先备份表结构和数据#导出命令 -u用户名 -p密码 -h ...

  2. ASP.NET (HttpModule,HttpHandler)

    asp.net 事件模型机制 ----------------------- 一 客户的请求页面由aspnet_isapi.dll这个动态连接库来处理,把请求的aspx文件发送给CLR进行编译执行,然 ...

  3. 排序算法_HeapSort

    大根堆排序的基本思想: 1) 先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区; 2) 再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,    由此得到新的无序区 ...

  4. 2013 ACM区域赛长沙 C Collision HDU 4793

    题意:在平面上0,0点,有一个半径为R的圆形区域,并且在0,0点固定着一个半径为RM(<R)的圆形障碍物,现在圆形区域外x,y,有一个半径 为r的,并且速度为vx,vy的硬币,如果硬币碰到了障碍 ...

  5. Linux I2C设备驱动编写(二)

    在(一)中简述了Linux I2C子系统的三个主要成员i2c_adapter.i2c_driver.i2c_client.三者的关系也在上一节进行了描述.应该已经算是对Linux I2C子系统有了初步 ...

  6. 找回linux丢失的磁盘空间

    最近一台服务器空间总是报警,磁盘空间不足. 使用 df 命令查看,磁盘空间耗用接近 100%,将机器上过期的数据以及日志清理掉,但是空间很快又是接近 100%. 使用 du 查看,想找出磁盘空间被耗用 ...

  7. UILabel字体加粗等属性和特效

    /* Accessing the Text Attributes text  property font  property textColor  property textAlignment  pr ...

  8. Contact Form 7邮件发送失败的解决办法

    一.contact form 7无法发送邮件的原因 对mail()函数的不支持. Contact Form 7表单提交失败在使用过程中会出现,归根结底原因在于wordpress主机问题,由于国 内很多 ...

  9. 转 python 之 分割参数getopt

    python 之 分割参数getopt os下有个方法walk,非常的好用,用来生成一个generator.每次可以得到一个三元tupple,其中第一个为起始路径,第二个为起始路径下的文件夹,第三个是 ...

  10. Linux命令之ssh

    一. 配置ssh 1. 命令 ssh-keygen [选项] 2. 说明 用于为“ssh”生成.管理和转换认证密钥,它支持RSA和DSA两种认证密钥 3. 选项 -C:添加注释 -f:指定用来保存密钥 ...