MongoDB基础教程系列--第六篇 MongoDB 索引
本文内容纲要:
-创建索引
-唯一索引
-复合索引
-删除索引
-查询分析
返回目录
使用索引可以大大提高文档的查询效率。如果没有索引,会遍历集合中所有文档,才能找到匹配查询语句的文档。这样遍历集合中整个文档的方式是非常耗时的,特别是处理大数据时,耗时几十秒甚至几分钟都是有可能的。
创建索引
MongoDB中,使用ensureIndex()方法创建索引。
格式
db.COLLECTION_NAME.ensureIndex({KEY:1})
其中,KEY表示要创建索引的字段名称,1表示按升序排列字段值。-1表示按降序排列。
范例
1、给user集合中name字段添加索引
>db.user.ensureIndex({"name":1})
>
MongoDB中用db.collection.getIndexes()方法查询集合中所有的索引,我们查询一下user中所有的索引。
>db.user.getIndexes()
[
{
"v":2,
"key":{
"_id":1
},
"name":"_id_",
"ns":"liruihuan.user"
},
{
"v":2,
"key":{
"age":1
},
"name":"name_1",
"ns":"liruihuan.user"
}
]
我们发现user中有两个索引,其中索引"_id_"是我们创建user集合时,MongoDB自动生成的索引。第二个索引就是我们刚才创建的索引,其中,name值"name_1"表示索引名称,MongoDB会自动生成的索引名称。当然,我们也可以自己指定索引的名称。
2、给user集合中age字段添加索引,并指定索引名称为"index_age_esc"。
>db.user.ensureIndex({"age":1},{name:"index_age_esc"})
>db.user.getIndexes()
[
{
"v":2,
"key":{
"_id":1
},
"name":"_id_",
"ns":"liruihuan.user"
},
{
"v":2,
"key":{
"age":1
},
"name":"index_age_esc",
"ns":"liruihuan.user"
}
]
指定索引名称用到的name参数,只是ensureIndex()方法可接收可选参数的其中一个,下表列出了ensureIndex()方法可接收的参数
Parameter | Type | Description |
---|---|---|
background | 布尔值 | 建索引过程会阻塞其它数据库操作,background可指定以后台方式创建索引,即增加"background"可选参数。"background"默认值为false。 |
unique | 布尔值 | 建立的索引是否唯一。指定为true创建唯一索引。默认值为false. |
name | 字符串 | 索引的名称。如果未指定,MongoDB的通过连接索引的字段名和排序顺序生成一个索引名称。 |
dropDups | 布尔值 | 在建立唯一索引时是否删除重复记录,指定true创建唯一索引。默认值为 false. |
sparse | 布尔值 | 对文档中不存在的字段数据不启用索引;这个参数需要特别注意,如果设置为true的话,在索引字段中不会查询出不包含对应字段的文档.。默认值为 false. |
expireAfterSeconds | 整型 | 指定一个以秒为单位的数值,完成TTL设定,设定集合的生存时间。 |
v | 索引版本 | 索引的版本号。默认的索引版本取决于mongod创建索引时运行的版本。 |
weights | 文档(document) | 索引权重值,数值在1到99,999之间,表示该索引相对于其他索引字段的得分权重。 |
default_language | 字符串 | 对于文本索引,该参数决定了停用词及词干和词器的规则的列表。默认为英语 |
language_override | 字符串 | 对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为language. |
唯一索引
MongoDB和关系型数据库一样都可以建立唯一索引,重复的键值就不能重新插入了,MongoDB用unigue来确定建立的索引是否为唯一索引,true表示为唯一索引,下面给user集合的name字段指定唯一索引
>db.user.ensureIndex({"name":1},{unique:true})
>db.user.find()
{"_id":ObjectId("58e1d2f0bb1bbc3245fa754b"),"name":"liruihuan","age":18,"sex":"man"}
>db.user.insert({"name":"liruihuan","age":18})
E11000duplicatekeyerrorcollection:liruihuan.userindex:name_1dupkey:{:\"liruihuan\"
可以看出,创建了唯一索引的字段,是不能再插入"liruihuan"的name值的。
复合索引
ensureIndex()方法中你也可以设置使用多个字段创建索引
范例
>db.user.ensureIndex({"name":1,"age":1})
>db.user.getIndexes()
[
{
"v":2,
"key":{
"_id":1
},
"name":"_id_",
"ns":"liruihuan.user"
},
{
"v":2,
"key":{
"name":1,
"age":1
},
"name":"name_1_age_1",
"ns":"liruihuan.user"
}
]
删除索引
MongoDB用dropIndex()方法删除索引
格式
db.COLLECTION_NAME.dropIndex()
**注:**dropIndex()方法可根据指定的索引名称或索引文档删除索引(_id上的默认索引除外)
范例
我们用两种方式删除掉user中name字段上的索引
>db.user.dropIndex("name_1")#根据索引名称删除索引
>db.user.dropIndex({"name":1})#根据索引文档删除索引
还可以用dropIndexes()删除集合中所有索引(_id上的默认索引除外)
>db.user.dropIndexes()
查询分析
查询分析是查询语句性能分析的重要工具。
MongoDB中查询分析用explain()和hint()方法
范例
我们向集合user中插入20万条数据,利用explain()查询建立索引前后,执行时间的比较,来看看建立索引对查询效率的提高程度。
第一步,向user中插入20万条数据
>db.user.remove({})
>for(vari=0;i<200000;i++){db.user.insert({"name":"lrh"+i,"age":18})}
第二步,删除user集合中字段name上的索引,然后查询name="lrh100000",利用explain("executionStats")查询此时执行的时间。**说明:**MongoDBexplain()方法在3.0以后版本中发生了很大改变,3.0之前版本直接用explain()就可以,不用传参数,如果想详细了解,请访问官网。
>db.user.dropIndexes()#删除所有索引
db.user.find({"name":"lrh100000"}).explain("executionStats")
{
"queryplanner":{
......
},
"executionStats":{
"executionTimeMillis":109
......
}
}
explain.executionStats.executionTimeMillis:表示查询所用的时间,单位是毫秒。
我们可以清楚的看出,没用索引查询用到的时间是109毫秒。
第三步,给user集合中name字段添加索引,然后再查询同一个条件,看执行查询所用了多久时间。
>db.user.ensureIndex({"name":1})
>db.user.find({"name":"lrh100000"}).explain("executionStats")
{
"queryplanner":{
"winningPlan":{
"inputStage":{
"indexName":"name_1"
......
}
.......
}
.......
},
"executionStats":{
"executionTimeMillis":1
......
}
}
如果用到了索引,explain()方法会返回winningPlan,标识用到的索引名称indexName
我们可以清楚到处,用了索引,执行时间只有1毫秒,可以看出,查询效率的提高可不是一星半点。
**注:**如果想更详细的了解explain()返回的参数,可以去官网看一下
第四步,这一步我们重点看看hint()方法的用法。hint()方法用来强制MongoDB使用一个指定的索引。
我们给user再添加一个{"name":1,"age":1},利用explain()方法,看一下用到了哪个索引。
>db.user.ensureIndex({"name":1,"age":1})
>db.user.find({"name":"lrh100000"}).explain("executionStats")
{
"queryplanner":{
"winningPlan":{
"inputStage":{
"indexName":"name_1_age_1"
......
}
.......
}
.......
}
......
}
可以看出,此时用到的索引是"name_1_age_1",如果我们想用索引"name_1",就可以用hint()方法指定。
>db.user.find({"name":"lrh100000"}).hint({"name":1}).explain("executionStats")
{
"queryplanner":{
"winningPlan":{
"inputStage":{
"indexName":"name_1"
......
}
.......
}
.......
}
......
}
业精于勤,荒于嬉;行成于思,毁于随。
如果你觉得这篇文章不错或者对你有所帮助,可以通过右侧【打赏】功能,给予博主一点点鼓励和支持
本文内容总结:创建索引,唯一索引,复合索引,删除索引,查询分析,
原文链接:https://www.cnblogs.com/liruihuan/p/6682575.html