MongoDB数据库索引,MongoDB数据库中索引和explain的

作者:计算机知识

前言

mongodb 索引使用

今天作者通过explain()方法来深入分析集结中索引的采用效益

前方的话

  索引常常能够十分大的增高查询的功能,假使未有索引,MongoDB在读取数据时必须扫描会集中的各样文件并选取那么些符合查询条件的笔录。这种扫描全集结的查询效用是很低的,非常在管理大量的数目时,查询能够要开支几10秒以致几分钟,那对网址的习性是那八个沉重的。本文将详细介绍MongoDB数据库索引

 

正文首要给大家介绍了有关MongoDB中索引和explain使用的连锁内容,分享出去供大家参考学习,上边话没有多少说了,来一齐探访详细的介绍:

  • 目录平常能够大幅的进步查询。
  • 目录是壹种数据结构,他募集一个会见中文档特定字段的值。
  • B-Tree索引来达成。

一.先是循环插入十0w条记下

引入

  索引可以增长查询效能,怎么样展示吗?接下去使用品质深入分析函数explain()来拓展分析表达

  首先,插入100000条数据

图片 1

  接着,不创造索引,来寻觅time范围在拾0和200之内的文书档案

图片 2

  由图中所知,totalDocsExamined值为一千00,表示查找了一千00个文书档案;nReturned值为101,表示回去了十一个文书档案;executionTimeMillis值为3九,表示开支了3玖ms

  下边,大家在time字段上确立目录

图片 3

  再度,搜索time范围在拾0和200之间的文书档案

图片 4

  由图能够,totalDocsExamined和nReturned值都以101,executionTimeMillis值为0,相当于从10二个文书档案中,找到了103个文书档案,查找的快慢趋近于0。简来说之,使用索引非常大地晋级了询问速度

 

mongodb 索引使用

for (var i = 0; i < 1000000; i   ) { db.person.insert({"name":"test" i, "cardNo":i}) }

概述

  索引是特殊的数据结构,以便于遍历的情势积累数据集的一小部分。 索引存款和储蓄特定字段或1组字段的值,依据索引中钦命的字段值排序

  使用索引,能够加速索引相关的询问,也应和地拉动一些害处

  1、扩大磁盘空间的开支。在目录比较多的情形下,索引文件所占用的上空有非常的大概率超越数据小编

MongoDB数据库索引,MongoDB数据库中索引和explain的使用教程。  2、在写入数据或更新数据时,对索引的有限帮衬一般是写之外的另一条逻辑,一定程度上,会降低写入质量

  可是,为了查询的短平快,这么些影响是值得的。有那多少个场地下,系统的品质下跌,与不客观的目录创立有关。所以,合理的始建索引,能够减去索引带来的倒霉的震慑

 

作用

db.collection.createIndex(keys, options)

keys由文档字段和索引类型组成。如{"name":1} key 表示字段 value 1,-1 1表示升序,-1降序

options 创建索引的选项。

二.查看插入效果

目录设置

【getIndexes()】

  使用getIndexes()方法来查询索引

db.collection_name.getIndexes()

  由下图能够,有"_id"和"time"多个目录

图片 5

【createIndex()】

db.COLLECTION_NAME.createIndex({KEY:1})

  语法中Key值为要开创的索引字段,壹为内定按升序创造索引,如若想按降序来创立索引钦命为-一就能够

图片 6 

  当然,也足以创设八个索引字段

db.COLLECTION_NAME.createIndex({k1:1,k2:1})

  在MongoDB3.0版本此前,使用的是ensureIndex()方法,未来ensureIndex()方法依旧得以应用,只是createIndex()方法的别称

  如若文档较多,创设索引必要开销一定的时日。要是系统负荷较重,且有为数非常多业已存在的文书档案,不可能一贯运用这一个命令实行创办,必要在利用数据库在此以前,就将引得创造完成。不然,严重影响数据库的性质

  [注意]目录能够另行创建,假使对曾经存在的目录再度创立,会直接再次来到成功

图片 7

  createIndex() 接收可选参数,可选参数列表如下:

Parameter     Type      Description
background    Boolean    建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,默认值为false
unique        Boolean    建立的索引是否唯一。指定为true创建唯一索引。默认值为false
name          string     索引的名称。如果未指定,MongoDB通过连接索引的字段名和排序顺序生成一个索引名称
dropDups      Boolean    在建立唯一索引时是否删除重复记录,指定 true 创建唯一索引。默认值为 false
sparse        Boolean    对文档中不存在的字段数据不启用索引;如果设置为true,索引字段中不会查询出不包含对应字段的文档。默认值为false
v             index version    索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本
weights       document   索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重
expireAfterSeconds  integer   指定一个以秒为单位的数值,完成 TTL设定,设定集合的生存时间
default_language    string    对于文本索引,该参数决定了停用词及词干和词器的规则的列表。 默认为英语
language_override   string    对于文本索引,该参数指定了包含在文档中的字段名,默认值为language

db.db_coll1.createIndex({time:1},{background:true})

【dropIndex()】

  使用db.collection_name.dropIndex({key:一})方法能够去除钦定索引

db.collection_name.dropIndex({key:1})

图片 8

  [注意]_id索引不或然被删除

图片 9

  除了采取键值对来删除索引,还足以采纳其name值来删除索引

  如下所示,{time:一}的name值为"time_1",使用db.db_coll1.dropIndex("time_壹")也足以去除索引

图片 10

【dropIndexes()】

  使用db.collection_name.dropIndexes()方法能够去除全数索引

db.collection_name.dropIndexes()

图片 11

 

  • 目录平时能够十分的大的抓牢查询。
  • 目录是1种数据结构,他搜聚2个聚焦普通话档特定字段的值。
  • B-Tree索引来达成。
参数 类型 描述
background boolean 创建索引在后台运行,不会阻止其他对数据库操作
unique boolean 创建唯一索引,文档的值不会重复
name string 索引名称,默认是:字段名_排序类型 开始排序
sparse boolean 过滤掉null,不存在的字段
> db.person.find(){ "_id" : ObjectId("5c7c9e15a795b984b42ad96b"), "name" : "test0", "cardNo" : 0 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad96c"), "name" : "test1", "cardNo" : 1 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad96d"), "name" : "test2", "cardNo" : 2 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad96e"), "name" : "test3", "cardNo" : 3 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad96f"), "name" : "test4", "cardNo" : 4 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad970"), "name" : "test5", "cardNo" : 5 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad971"), "name" : "test6", "cardNo" : 6 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad972"), "name" : "test7", "cardNo" : 7 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad973"), "name" : "test8", "cardNo" : 8 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad974"), "name" : "test9", "cardNo" : 9 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad975"), "name" : "test10", "cardNo" : 10 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad976"), "name" : "test11", "cardNo" : 11 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad977"), "name" : "test12", "cardNo" : 12 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad978"), "name" : "test13", "cardNo" : 13 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad979"), "name" : "test14", "cardNo" : 14 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad97a"), "name" : "test15", "cardNo" : 15 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad97b"), "name" : "test16", "cardNo" : 16 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad97c"), "name" : "test17", "cardNo" : 17 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad97d"), "name" : "test18", "cardNo" : 18 }{ "_id" : ObjectId("5c7c9e15a795b984b42ad97e"), "name" : "test19", "cardNo" : 19 }Type "it" for more

索引属性

【TTL】

  过期索引又称作TTL索引,是1种独特类型的单字段索引,首要用来当满足有些特定时间之后自动删除相应的文书档案。也等于说集结中的文书档案有一定的有效期,超过限期的文书档案就能够失灵,会被移除。约等于数据会晚点。过期的多寡没有必要保留,这种景况适用于如机器生成的事件数量,日志和对话音讯等等

  一样地,过期索引使用createIndex()方法来创设,但它扶助第3个参数expireAfterSeconds,用来钦点多少秒过期可能隐含过期日期值的数组

 db.eventlog.createIndex( { x: 1 }, { expireAfterSeconds: 3600 } )

  以下示例中,在60s后,会删除time文书档案

图片 12

  使用过期索引,有以下几点注意事项

  一、存款和储蓄在过期索引字段的值必须是点名的日子项目。必须是ISODate可能ISODate数组,不能够选用时间戳,不然不可能被自动删除

  以下示例中time设置了ISODate类型的值,该值到60s后会被活动删除

图片 13

  以下示例中,time设置了时光戳,该值到60s后无法被删去

图片 14

  贰、若是钦命了ISODate时间数组,则依据最小的时光实行删减

  三、过期索引不可能是复合索引

  四、删除时间是不正确的。删除进程是由后台程序每60s跑叁回,而且删除也急需部分时间,存在相对误差。所以,即便设置的到期时间与目前时刻的间距小于60s,则文书档案最少也要60s才干被删去

【唯一性】

  索引的脾性能够享有唯1性,即唯一索引,只要设置索引属性中的unique为true就可以,默感觉false。唯一索引用于确定保障索引字段不存款和储蓄重复的值,即强制索引字段的唯一性。缺省情状下,mongodb的_id字段在创立集合的时候会自行创造1个唯一索引

db.collection_name.createIndex({},{unique:true})

  如下图所示,在私下认可景况下,不是并世无双索引

图片 15

  在设置unique:true后,不能插入重复的值

图片 16

左近错误

  如下图所示,设置的a字段为唯一索引,b字段也无从输入重复的值。那是因为设置a字段为唯一索引,插入数据b:10,也便是a:null,再插入b:10时,相当于又插入了a:null。而a:null和a:null是重新的,而a字段是并世无双索引,无法再一次。所以,不可能插入重复的b:十

图片 17

【稀疏性】

  索引的个性能够具有稀疏性,即稀疏索引,只要设置索引属性中的sparse为true就可以,默以为false

db.collection_name.createIndex({},{sparse:true})

  稀疏性的两样代表了MongoDB在拍卖索引中存在但文书档案中不设有的字段的二种分化的办法

  稀疏索引,也称之为间隙索引便是创造索引的索引列在少数文档上列不存在,导致索引存在间隙。

  假使,在2个会面中,创立了x字段上的目录。可是,插入的文书档案中并不分包x字段。在暗中认可情况下,MongoDB照旧会为那条不存在的字段创造索引。假若把那条索引创造为稀疏索引,则那条索引将不会被运用

  要是数额会集福建中国广播公司大文书档案在创制索引的字段上并从未值,使用稀疏索引能够减掉磁盘占用,且拉长插入速度

$exits

  使用稀疏索引时,大概会带来一些隐患。MongoDB提供了一种$exits操作符,$exits表示字段是还是不是存在

图片 18

  由下图所示,创制了{m:1}的稀疏索引,使用find()方法找出不设有m字段的文书档案时,结果现身了。是因为,MongoDB并未使用稀疏索引来查询

  假若应用hint()方法强制使用稀疏索引来查找索引上存在而文档中不存在的字段,则没有结果。再度表明稀疏索引不可能用来查找索引上存在,但文书档案里不存在的字段

图片 19

 

创办索引

 db.collection.getIndexes()

 { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.userdatas" }, { "v" : 1, "key" : { "name" : 1 //索引字段 }, "name" : "name_1", //索引名称 "ns" : "leyue.userdatas" }

 db.collection.dropIndex 删除指定的索引。 db.collection.dropIndexes() 删除除了_id 以外的所有索引。

三.尚未索引意况下询问深入分析

目录体系

  MongoDB扶助基于集结文书档案上任性列创立索引。缺省事态下,全体的文书档案的_id列上都设有一个索引。基于业务的需求,能够遵照一些关键的询问和操作来创制一些额外的目录。那些索引能够是单列,也可是多列(复合索引),多键索引,地理空间引得,全文索引等

  MongoDB支持6种索引,包括

  1、_id索引

  二、单键索引

  三、多键索引

  四、复合索引

  伍、全文索引

  6、地理地方索引

【_id索引】

  _id索引是绝大好些个凑合暗中认可建构的目录,对于各个插入的数额,MongDB都会自动生成一条唯一的_id字段

  由下图所示,在未插入其它索引在此之前,已经存在_id索引

图片 20

【单键索引】

  单键索引是最普通的目录,与_id索引差别,单键索引不会自动成立

  例如,一条记下,格局为{x:一,y:二,z:三},在x字段上营造目录,之后就能够使用x为标准进行询问

图片 21

【多键索引】

  在MongoDB中能够根据数组来创制索引。mongodb为数组每三个因素创立索引值。多键索引帮衬数组字段的飞快查询。多键索引能够基于字符串,数字数组以及嵌套文书档案进行创办

  多键索引与单键索引创立情势同样,差距在于字段的值。单键索引的值为单一的值,如1个字符串、数字或日期。多键索引的值具有四个记录,如二个数组

  假如mongoDB中插入数组类型的多键数据,索引是自行构建的,无需刻意钦命。不过,使用getIndexes()方法并不曾多键索引,除非显式地创设多键索引

【复合索引】

  MongoDB帮助复合索引,将要多少个键组合到联合创设索引。该格局叫做复合索引,恐怕也叫组合索引,该方法能够满意多键值相称查询利用索引的事态。其次复合索引在利用的时候,也得以由从前缀法来选择索引

  [注意]随便复合索引字段不能够赶上三13个

  举例,插入{x:一,y:二,z:叁}的笔录,当供给遵照x与y的值举办查询时,就要求创设x与y的复合索引。接着,就足以使用x和y作为基准举行查询

db.db_coll1.createIndex({x:1,y:1})
db.db_coll1.createIndex({x:-1,y:1})
db.db_coll1.createIndex({x:-1,y:-1})
db.db_coll1.createIndex({x:1,y:-1})
db.db_coll1.createIndex({y:1,x:1})
db.db_coll1.createIndex({y:-1,x:1})
db.db_coll1.createIndex({y:-1,x:-1})
db.db_coll1.createIndex({y:1,x:-1})

  复合索引成立时按升序或降序来内定其排列方式。对于单键索引,其顺序并不是特意主要,因为MongoDB能够在任1方向遍历索引。对于复合索引,按何种措施排序能够调控该索引在查询中能还是不能够被利用到

  x与y的复合索引共包括以上捌种状态,x和y的程序次序分歧,升序或降序不相同,都会时有产生差别的目录。而查询优化器,会使用大家树立的这么些索引来创立查询方案,最后选抽取最优的目录来查询数据

  索引前缀指的是复合索引的子集

  假设存在如下索引

{ "item": 1, "location": 1, "stock": 1 }

  那存在下列索引前缀

{ item: 1 }
{ item: 1, location: 1 }

  在MongoDB中,下列查询过滤条件意况中,索引将会被选用到

item字段
item字段   location字段
item字段   location字段   stock字段
item字段   stock字段(尽管索引被使用,但不高效)

  以下过滤条件查询情况,索引将不会被选用到

location字段
stock字段
location   stock字段

 

db.collection.createIndex(keys, options)
  • index 是字符串 表示依据索引名称 name 删除字段。
  • index 是{字段名称:1} 表示依照key 删除索引。
> db.person.find({"name":"test890000"}).explain("executionStats"){ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.person", "indexFilterSet" : false, "parsedQuery" : { "name" : { "$eq" : "test890000" } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "name" : { "$eq" : "test890000" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 389, "totalKeysExamined" : 0, "totalDocsExamined" : 1000000, "executionStages" : { "stage" : "COLLSCAN", "filter" : { "name" : { "$eq" : "test890000" } }, "nReturned" : 1, "executionTimeMillisEstimate" : 232, "works" : 1000002, "advanced" : 1, "needTime" : 1000000, "needYield" : 0, "saveState" : 7814, "restoreState" : 7814, "isEOF" : 1, "invalidates" : 0, "direction" : "forward", "docsExamined" : 1000000 } }, "serverInfo" : { "host" : "shengyulongdeMacBook-Pro-2.local", "port" : 27017, "version" : "4.0.3", "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c" }, "ok" : 1}

全文索引

【创建】

  全文索引也叫做文本索引,常见于搜索框中。我们在研究框中输加入关贸总协定协会键词,举例"HTML",不唯有标题中包涵"HTML"的篇章会被搜索出来,而且小说中设有"HTML"的稿子也会被寻觅出来

  为了索引三个囤积字符串或然字符串数组的键,要求在开创选项中蕴藏那些键并钦命为 "text" ,如下:

db.reviews.createIndex( { comments: "text" } )

  假若急需在多少个字段上创办全文索引,则能够复合索引

db.reviews.createIndex(
   {
     subject: "text",
     comments: "text"
   }
 )

  假若急需对具有字段成立全文索引,则须要使用$xx标记

db.collection_name.createIndex( { "$**": "text" } )

  [注意]一个聚焦最七只可以成立 一个 文本 索引

【使用】

  要是运用全文索引举办检索,则须求接纳如下格式

db.collection_name.find({$text:{$search: '...'}})

  假如使用如下的数据结构来存储1个全体的文章,author存款和储蓄小编,title存款和储蓄题目,article存款和储蓄作品内容

{author:"",title:"",article:""}

  现在来增加一些数目,并对具有字段成立全文索引

图片 22

  上边来索求'huochai',可一板一眼到叁条记下

图片 23

  借使寻找'a二',则不得不寻觅到第一条记下

图片 24

  假使寻找'a一 a二 a三',则一定于或的涉嫌,a一 或 a2 或 a三,能够寻觅到叁条记下

图片 25

  假设搜索'huochai -css',也便是查找包罗'huochai',但不包括'css'的笔录,包涵第一和第3条

图片 26

  即使要查究且涉及,比方同一时间富含huochai和css的笔录,则需求在内部增添引号," "huochai" "css" "

  [注意]只帮助双引号

图片 27

【相似度】

  全文索引有2个相似度的定义,表示全文索引的物色条件与记录的从头到尾的经过有多么相似

  在find()方法的第壹个参数中,score是1个数字,该数字越大,表示相似度越高

db.collection_name.find({$text:{$search: '...'}},{score:{$meta:"textScore"}})

  未来,再插入一条内容,笔者为'huochai'

图片 28

  然后开首查找'huochai',并涵盖相似度

图片 29

  下边采取相似度排序,相似度高的排在前边

sort({score:{$meta:"textScore"}})

图片 30

【限制】

  壹、每一趟查询,只可以钦赐多少个$text查询

  贰、$text查询不能出现在$nor查询中

  三、查询中1旦含有了$text,hint()将不再起功用

  4、只好对全体单词查询,无法对单词的截取部分查询。类似地,中文做全文查询的时候,只好查询壹段话中有空格的该字也许词

 

keys

肆.给name字段创设升序索引

地理地点索引

  一般地,地理地方索引能够实现诸如按距离排序的饭店、在某区域内的合营社筛选等

  能够将有个别点的岗位存款和储蓄在MongoDB中,成立地理地方索引索引后,可以依照岗位来查究别的点。地理地点索引可以分成二种:一种是二d索引,用于存款和储蓄和探求平面上的点;另一种是2dsphere索引,用于存款和储蓄和搜索球面上的点

  查找方法相似有三种:1种是搜索距离有些点一定限制内的点;另壹种是寻找包蕴在某区域内的点

【2D索引】

  二D索引的始建格局如下

db.<collection>.createIndex( { <location field> : "2d" , <additional field> : <value> } , { <index-specification options> } )

  options包罗如下参数

{ min : <lower bound> , max : <upper bound> , bits : <bit precision> }

图片 31

  在mongodb中采纳经纬度表示地点,[经度, 纬度]。经度范围在[-180,180],纬度范围在[-90,90]

  [注意]私下认可边界允许插入大于90或低于-90的不成立纬度值的文书档案。而对此这么不创造的点的地理查询,数据库行为是不足预言的。所以,尽量防止插入凌驾范围的维度值

图片 32

  二D索引的查询办法有三种,包涵$near、$geoNear、$geoWithin

  一种是运用$near查询,即查询距离有些点以来的点,私下认可重临玖十九个

db.<collection>.find( { <location field> :{ $near : [ <x> , <y> ] } } )

图片 33

  $maxDistance能够设置离当下点最远的相距

图片 34

  $minDistance可以设置离当下点以来的相距

图片 35

  另一种是应用$geoNear查询,$geoNear使用runCommand命令进行利用

db.runCommand({geoNear:<collection_name>,near:[x,y],minDistance:..,maxDistance:..,num:...})

图片 36

  另1种是运用$geoWithin查询,即查询有些形状内的点

  在mongodb中,有三种形态,蕴含矩形、圆形和三头形,使用办法如下

db.<collection>.find( { <location field> :{ $geoWithin :{ $box|$polygon|$center : <coordinates>} } } )

  第二种是矩形,使用$box表示

{$box:[[x1,y1],[x2,y2]]}

图片 37

  第两种是圈子,使用$center表示

{$center:[[<x1>,<y1>],r]}

图片 38

  第二种是多方面形,使用$polygon表示

{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>],...]}

图片 39

【2dsphere索引】 

  ②dsphere索引的创始格局如下

db.collection_name.createIndex({a:"2dsphere"})

  地点表示方法不再是简轻巧单的中纬度,而是一种吉优JSON的意味方法,用来说述二个点、一条直线、多边形等形象,格式如下

{type:"",coordinates:[<coordinates>]}

 

  • keys由文书档案字段和索引类型组成。如{"name":一}
  • key 代表字段 value 一,-1  一象征升序,-一降序
 db.userdatas.find(){ "_id" : ObjectId("597f357a09c84cf58880e412"), "name" : "u3", "age" : 32 }{ "_id" : ObjectId("597f357a09c84cf58880e411"), "name" : "u4", "age" : 30, "score" : [ 7, 4, 2, 0 ] }{ "_id" : ObjectId("597fcc0f411f2b2fd30d0b3f"), "age" : 20, "score" : [ 7, 4, 2, 0, 10, 9, 8, 7 ], "name" : "lihao" }{ "_id" : ObjectId("597f357a09c84cf58880e413"), "name" : "u2", "age" : 33, "wendang" : { "yw" : 80, "xw" : 90 } }{ "_id" : ObjectId("5983f5c88eec53fbcd56a7ca"), "date" : ISODate("2017-08-04T04:19:20.693Z") }{ "_id" : ObjectId("597f357a09c84cf58880e40e"), "name" : "u1", "age" : 26, "address" : "中国砀山" }{ "_id" : ObjectId("597f357a09c84cf58880e40f"), "name" : "u1", "age" : 37, "score" : [ 10, 203, 12, 43, 56, 22 ] }{ "_id" : ObjectId("597f357a09c84cf58880e410"), "name" : "u5", "age" : 78, "address" : "china beijing chaoyang" }

 // 创建索引 db.userdatas.createIndex({"name":1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } // 查看索引 db.userdatas.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.userdatas" }, { "v" : 1, "key" : { "name" : 1 }, "name" : "name_1", "ns" : "leyue.userdatas" } ]

 db.userdatas.createIndex({"name":1}) db.userdatas.createIndex({"name":1},{"name":"myindex"}) db.userdatas.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.userdatas" }, { "v" : 1, "key" : { "name" : 1 }, "name" : "myindex", "ns" : "leyue.userdatas" } ]

当mongodb 集合里面的数据过大时 创建索引很耗时,可以在放在后台运行。

 db.userdatas.dropIndex("myindex") db.userdatas.createIndex({"name":1},{"name":"myindex","background":true})

 db.userdatas.createIndex({"age":-1},{"name":"ageIndex","unique":true,"sparse":true}) db.userdatas.getIndexes()[ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.userdatas" }, { "v" : 1, "key" : { "name" : 1 }, "name" : "myindex", "ns" : "leyue.userdatas", "background" : true }, { "v" : 1, "unique" : true, "key" : { "age" : -1 }, "name" : "ageIndex", "ns" : "leyue.userdatas", "sparse" : true }]// 插入一个已存在的age db.userdatas.insert({ "name" : "u8", "age" : 32})WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error index: leyue.userdatas.$ageIndex dup key: { : 32.0 }" }})

 db.userdatas.createIndex({"name":1,"age":-1}) db.userdatas.getIndexes()[ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.userdatas" }, { "v" : 1, "key" : { "name" : 1, "age" : -1 }, "name" : "name_1_age_-1", "ns" : "leyue.userdatas" }]

db.system.indexes.find(){ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.userdatas" }{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.scores" }{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.test" }{ "v" : 1, "key" : { "user" : 1, "name" : 1 }, "name" : "myindex", "ns" : "leyue.test" }{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "leyue.mycapped" }{ "v" : 1, "key" : { "user" : 1 }, "name" : "user_1", "ns" : "leyue.test" }{ "v" : 1, "key" : { "name" : 1 }, "name" : "myindex", "ns" : "leyue.userdatas" }
> db.person.createIndex({"name":1}){ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1}

options

  • 一:创设索引时,一意味按升序存款和储蓄,-1意味按降序存储。

  • 二:能够成立复合索引,要是想用到复合索引,必须在询问条件中涵盖复合索引中的前N个索引列

  • 3: 假如查询条件中的键值顺序和复合索引中的创造顺序不等同的话,MongoDB能够智能的增派大家调节该每一种,以便使复合索引能够为查询所用。

  • 四: 可认为内嵌文书档案成立索引,其规则和经常文书档案创制索引是同样的。

  • 5: 一次查询中只可以使用二个索引,$or特殊,可以在各种分支条件上采用四个目录。

  • 6: $where,$exists不能够利用索引,还或许有部分低功能的操作符,举例:$ne,$not,$nin等。

  • 7: 设计七个字段的目录时,应该尽量将用以规范匹配的字段放在索引的前边。

5.explain查看索引解析

options 创立索引的选项。

> db.person.find({"name":"test890000"}).explain("executionStats"){ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "test.person", "indexFilterSet" : false, "parsedQuery" : { "name" : { "$eq" : "test890000" } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "name" : 1 }, "indexName" : "name_1", "isMultiKey" : false, "multiKeyPaths" : { "name" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "name" : [ "["test890000", "test890000"]" ] } } }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 1, "executionTimeMillis" : 1, "totalKeysExamined" : 1, "totalDocsExamined" : 1, "executionStages" : { "stage" : "FETCH", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "works" : 2, "advanced" : 1, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "docsExamined" : 1, "alreadyHasObj" : 0, "inputStage" : { "stage" : "IXSCAN", "nReturned" : 1, "executionTimeMillisEstimate" : 0, "works" : 2, "advanced" : 1, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "keyPattern" : { "name" : 1 }, "indexName" : "name_1", "isMultiKey" : false, "multiKeyPaths" : { "name" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "name" : [ "["test890000", "test890000"]" ] }, "keysExamined" : 1, "seeks" : 1, "dupsTested" : 0, "dupsDropped" : 0, "seenInvalidated" : 0 } } }, "serverInfo" : { "host" : "shengyulongdeMacBook-Pro-2.local", "port" : 27017, "version" : "4.0.3", "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c" }, "ok" : 1}
参数 类型 描述
background boolean 创建索引在后台运行,不会阻止其他对数据库操作
unique boolean 创建唯一索引,文档的值不会重复
name string 索引名称,默认是:字段名_排序类型 开始排序
sparse boolean 过滤掉null,不存在的字段
 db.collection.explain().<method>
  • executionStats.nReturned:重回的文书档案的数目
  • executionStats.execution提姆eMillis:推行的年月,单位
  • executionStats.totalKeysExamined: 索引围观条目款项。
  • executionStats.totalDocsExamined: 文书档案扫描条目款项

查阅索引

explain() 能够安装参数 :

比较之下深入分析

 db.collection.getIndexes()


 {
  "v" : 1,
  "key" : {
   "_id" : 1
  },
  "name" : "_id_",
  "ns" : "leyue.userdatas"
 },
 {
  "v" : 1,
  "key" : {
   "name" : 1 //索引字段
  },
  "name" : "name_1", //索引名称
  "ns" : "leyue.userdatas"
 }
  • queryPlanner。

  • executionStats。

  • allPlansExecution。

使用索引 不使用索引
搜索时间 1ms 389ms
索引扫描条目 1 0
文档扫描条目 1 1000000

删除索引

选取索引和不选择索引真是差距巨大啊!!!

    db.collection.dropIndex(index)删除钦赐的目录。

for(var i=0;i<100000;i  ) { db.test.insert({"user":"user" i});}

    db.collection.dropIndexes()剔除除了_id 以外的有着索引。

并未采纳索引
 db.test.explain("executionStats").find({"user":"user200000"}){ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "leyue.test", "indexFilterSet" : false, "parsedQuery" : { "user" : { "$eq" : "user200000" } }, "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "user" : { "$eq" : "user200000" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 2, "executionTimeMillis" : 326, "totalKeysExamined" : 0, "totalDocsExamined" : 1006497, "executionStages" : { "stage" : "COLLSCAN", "filter" : { "user" : { "$eq" : "user200000" } }, "nReturned" : 2, "executionTimeMillisEstimate" : 270, "works" : 1006499, "advanced" : 2, "needTime" : 1006496, "needYield" : 0, "saveState" : 7863, "restoreState" : 7863, "isEOF" : 1, "invalidates" : 0, "direction" : "forward", "docsExamined" : 1006497 } }, "serverInfo" : { "host" : "lihaodeMacBook-Pro.local", "port" : 27017, "version" : "3.2.1", "gitVersion" : "a14d55980c2cdc565d4704a7e3ad37e4e535c1b2" }, "ok" : 1}
  • executionStats.executionTimeMillis: query的欧洲经济共同体查询时间。

  • executionStats.nReturned: 查询重回的条目。

  • executionStats.totalKeysExamined: 索引围观条款。

  • executionStats.totalDocsExamined: 文书档案扫描条款。

execution提姆e米尔is = 32六 query 推行时间nReturned=2重回两条数据totalKeysExamined=0 未有运用索引totalDocsExamined 全文书档案扫描

神奇状态:nReturned=totalKeysExamined & totalDocsExamined=0

  • index 是字符串 表示依据索引名称 name 删除字段。
  • index 是{字段名称:1} 表示依照key 删除索引。
Stage状态深入分析
stage 描述
COLLSCAN 全表扫描
IXSCAN 扫描索引
FETCH 根据索引去检索指定document
SHARD_MERGE 将各个分片返回数据进行merge
SORT 表明在内存中进行了排序
LIMIT 使用limit限制返回数
SKIP 使用skip进行跳过
IDHACK 针对_id进行查询
SHARDING_FILTER 通过mongos对分片数据进行查询
COUNT 利用db.coll.explain之类进行count运算
COUNTSCAN count不使用Index进行count时的stage返回
COUNT_SCAN count使用了Index进行count时的stage返回
SUBPLA 未使用到索引的$or查询的stage返回
TEXT 使用全文索引进行查询时候的stage返回
PROJECTION 限定返回字段时候stage的返回
  • 对于普通查询,笔者盼望见到stage的结缘(查询的时候尽量用上索引):

    Fetch IDHACK

    Fetch ixscan

    Limit (Fetch ixscan)

    PROJECTION ixscan

    SHARDING_FITER ixscan

    COUNT_SCAN

  • 不愿意见到包罗如下的stage:

COLLSCAN,SORT(使用sort不过无index),不客观的SKIP,SUBPLA(未用到index的$or),COUNTSCAN(不选取index进行count)

创建/查看/删除 示例

接纳索引
 db.test.createIndex({"user":1},{"name":"myindex","background":true}) db.test.explain("executionStats").find({"user":"user200000"}){ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "leyue.test", "indexFilterSet" : false, "parsedQuery" : { "user" : { "$eq" : "user200000" } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "user" : 1 }, "indexName" : "myindex", "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "user" : [ "["user200000", "user200000"]" ] } } }, "rejectedPlans" : [ ] }, "executionStats" : { "executionSuccess" : true, "nReturned" : 2, "executionTimeMillis" : 0, "totalKeysExamined" : 2, "totalDocsExamined" : 2, "executionStages" : { "stage" : "FETCH", "nReturned" : 2, "executionTimeMillisEstimate" : 0, "works" : 3, "advanced" : 2, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "docsExamined" : 2, "alreadyHasObj" : 0, "inputStage" : { "stage" : "IXSCAN", "nReturned" : 2, "executionTimeMillisEstimate" : 0, "works" : 3, "advanced" : 2, "needTime" : 0, "needYield" : 0, "saveState" : 0, "restoreState" : 0, "isEOF" : 1, "invalidates" : 0, "keyPattern" : { "user" : 1 }, "indexName" : "myindex", "isMultiKey" : false, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 1, "direction" : "forward", "indexBounds" : { "user" : [ "["user200000", "user200000"]" ] }, "keysExamined" : 2, "dupsTested" : 0, "dupsDropped" : 0, "seenInvalidated" : 0 } } }, "serverInfo" : { "host" : "lihaodeMacBook-Pro.local", "port" : 27017, "version" : "3.2.1", "gitVersion" : "a14d55980c2cdc565d4704a7e3ad37e4e535c1b2" }, "ok" : 1}
  • executionTimeMillis: 0
  • totalKeysExamined: 2
  • totalDocsExamined:2
  • nReturned:2
  • stage:IXSCAN
  • 行使索引和不利用天差地别,合理选取索引,三个汇集适合做 四-伍 个目录。

查看数据

  db.userdatas.find()
{ "_id" : ObjectId("597f357a09c84cf58880e412"), "name" : "u3", "age" : 32 }
{ "_id" : ObjectId("597f357a09c84cf58880e411"), "name" : "u4", "age" : 30, "score" : [ 7, 4, 2, 0 ] }
{ "_id" : ObjectId("597fcc0f411f2b2fd30d0b3f"), "age" : 20, "score" : [ 7, 4, 2, 0, 10, 9, 8, 7 ], "name" : "lihao" }
{ "_id" : ObjectId("597f357a09c84cf58880e413"), "name" : "u2", "age" : 33, "wendang" : { "yw" : 80, "xw" : 90 } }
{ "_id" : ObjectId("5983f5c88eec53fbcd56a7ca"), "date" : ISODate("2017-08-04T04:19:20.693Z") }
{ "_id" : ObjectId("597f357a09c84cf58880e40e"), "name" : "u1", "age" : 26, "address" : "中国砀山" }
{ "_id" : ObjectId("597f357a09c84cf58880e40f"), "name" : "u1", "age" : 37, "score" : [ 10, 203, 12, 43, 56, 22 ] }
{ "_id" : ObjectId("597f357a09c84cf58880e410"), "name" : "u5", "age" : 78, "address" : "china beijing chaoyang" }

本文由bwin必赢发布,转载请注明来源

关键词: 索引 MongoDB explain 必赢a