一.索引详讲

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

准备工作,向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. [转]NHibernate之旅(2):第一个NHibernate程序

    本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4-1.设计持久化类 4-2.编写映射文件 5.数据访问层 5-1. ...

  2. ReentrantLock Condition 实现消费者生产者问题

    import java.util.LinkedList; import java.util.Queue; import java.util.concurrent.ExecutorService; im ...

  3. fopen\fread\fwrite\fscanf\fprintf\fseek\feof\rewind\fgets\fputc等系列函数使用总结

    转载自:http://blog.csdn.net/xidianzhimeng/article/details/23541289 1 fopen 函数原型:FILE * fopen(const char ...

  4. 神经网络中误差反向传播(back propagation)算法的工作原理

    注意:版权所有,转载需注明出处. 神经网络,从大学时候就知道,后面上课的时候老师也讲过,但是感觉从来没有真正掌握,总是似是而非,比较模糊,好像懂,其实并不懂. 在开始推导之前,需要先做一些准备工作,推 ...

  5. 解决Scrapy抓取中文结果保存为文件时的编码问题

    import json import codecs # Define your item pipelines here # # Don't forget to add your pipeline to ...

  6. [LeetCode] 287. Find the Duplicate Number 解题思路

    Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), pro ...

  7. 【转】开始使用Mac OS X——写给Mac新人

    写这篇文档的原因有两个,一.身边使用Mac的朋友越来越多,经常会有人来咨询一些常见的使用问题,比如:“为什么把界面右上角的红色按钮叉掉,程序还没有关闭?”之类.而且我也不愿意看到很多人使用OSX时仅仅 ...

  8. 使用wampserver安装Composer的注意事项

    http://getcomposer.org/Composer-Setup.exe 修改C:\wamp\bin\php\php5.3.10中php.ini中的配置 在php.ini中开启php_ope ...

  9. ios 游戏《魂斗罗》 AL文件素材破解

    1.破解原理非常简单就是找png的8字节的前缀(baidu png 文件编码格式). 2.破解就图就可以看见了 3.这样一个个个的改是不是非常麻烦,所有我专门写了个py脚本在干这事!一步搞定! 源码如 ...

  10. linux内核--内核内存管理

    如题目所示,为什么要称作“内核内存管理”,因为内核所需要的内存和用户态所需要的内存,这两者在管理上是不一样的. 这篇文章描述内核的内存管理,用户态的内存管理在以后的文章中讲述. 首先简单的说明一下下面 ...