MongoDB的索引
一.索引详讲
索引是什么,索引就好比一本书的目录,当我们想找某一章节的时候,通过书籍的目录可以很快的找到,所以适当的加入索引可以提高我们查询的数据的速度。
准备工作,向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的索引的更多相关文章
- MongoDB的索引(三)
MongoDB的索引: 1. _id索引 该索引是大多数集合默认创建的索引,也就是说用户每插入一个数据,MongoDB会自动生成一条唯一的_id字段. 2. 单键索引 单键索引是最普通的索引,它不会自 ...
- MongoDB 覆盖索引查询
MongoDB 覆盖索引查询 官方的MongoDB的文档中说明,覆盖查询是以下的查询: 所有的查询字段是索引的一部分 所有的查询返回字段在同一个索引中 由于所有出现在查询中的字段是索引的一部分, Mo ...
- MongoDB数据库索引
前面的话 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录.这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查 ...
- MongoDB数据库索引构建情况分析
前面的话 本文将详细介绍MongoDB数据库索引构建情况分析 概述 创建索引可以加快索引相关的查询,但是会增加磁盘空间的消耗,降低写入性能.这时,就需要评判当前索引的构建情况是否合理.有4种方法可以使 ...
- MongoDB索引(一) --- 入门篇:学习使用MongoDB数据库索引
这个系列文章会分为两篇来写: 第一篇:入门篇,学习使用MongoDB数据库索引 第二篇:进阶篇,研究数据库索引原理--B/B+树的基本原理 1. 准备工作 在学习使用MongoDB数据库索引之前,有一 ...
- MongoDb进阶实践之七 MongoDB的索引入门
一.引言 好久没有写东西了,MongoDB系列的文章也丢下好长时间了.今天终于有时间了,就写了一篇有关索引的文章.一说到"索引",用过关系型数据库的人都应该知道它是一个什么 ...
- 给MongoDB添加索引
用过数据库的都知道,数据库索引与书籍的索引类似,都是用来帮助快速查找的. MongoDB的索引跟关系型数据库的索引几乎一致. 1. 索引的创建 mongodb采用ensureInd ...
- linux环境给mongodb创建索引
首先我们来了解索引,如果有基础的可以直接看最后面的操作. 可参照 DoNotStop 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/u013725455/artic ...
- MongoDB复合索引详解
摘要: 对于MongoDB的多键查询,创建复合索引可以有效提高性能. 什么是复合索引? 复合索引,即Compound Index,指的是将多个键组合到一起创建索引,这样可以加速匹配多个键的查询.不妨通 ...
- 五、MongoDB的索引
一.MongoDB的下载.安装与部署 二.MongoDB的基础知识简介 三.MongoDB的创建.更新和删除 四.MongoDB的查询 五.MongoDB的索引 1.简介 它就像是一本书的目录,如果没 ...
随机推荐
- 解决Windows8系统磁盘占用太多100%或99%
关闭家庭组功能:WIN+R运行Services.msc,找到 HomeGroup Listener 和 HomeGroup Provider 服务,分别停止和禁用这2个服务.然后重新启动Windows ...
- HDOJ/HDU 2163 Palindromes(判断回文串~)
Problem Description Write a program to determine whether a word is a palindrome. A palindrome is a s ...
- 28个Unix/Linux的命令行神器
下面是Kristóf Kovács收集的28个Unix/Linux下的28个命令行下的工具(原文链接),有一些是大家熟悉的,有一些是非常有用的,有一些是不为人知的.这些工具都非常不错,希望每个人都知道 ...
- Python中的引用的使用注意
关于Python中的引用的一些使用注意 在python中,在创建一个对象并给它赋予一个变量时,这个赋予的变量仅仅是一个引用它所代表的对象.也就是说新创建的对象只是指向计算机中储存那个对象的内存. 比如 ...
- CF 294C(Java大数做计数)
题目链接:http://codeforces.com/contest/294/problem/C 代码: import java.util.*; import java.math.*; public ...
- Dijkstra算法求解最短路径分析
最短路径是图论算法中的经典问题.图分为有向图.无向图,路径权值有正值.负值,针对不同的情况需要分别选用不同的算法.在维基上面给出了各种不同的场景应用不同的算法的基本原则:最短路问题. 针对无向图,正权 ...
- Classical Inheritance in JavaScript
JavaScript is a class-free, object-oriented language, and as such, it uses prototypal inheritance in ...
- STM32 IAP 在线更新程序 为什么有时行 有时又不行 感觉不可靠 问题解决
搞了一天才发现 在MDK设置选项中有个"linker"选项卡 , 需要在Project->Options->Linker中将Use Memory Layout from ...
- 界面编程模仿篇(QQ登录界面逼真篇)
写了好多天的爬虫,偷空前前后后用了两天的时间(排除吃饭睡觉)写完了这个QQ登录界面,看起来还凑和着吧,如果是的大神的,莫见笑,纯属业余作品,废话先不多说,截图如下,其中第二幅图片中的红色方框部份有待完 ...
- docker学习资料整理(持续更新中..)
docker最近可以说火得一踏糊涂,跟 51大神在交流技术的时候这个东西会多次被提到,当我们还玩vm+linux/freebsd的时候,人家已经上升到更高层次了,这就是差距,感觉好高大上的样子,技术之 ...