返回目录html
使用索引能够大大提升文档的查询效率。若是没有索引,会遍历集合中全部文档,才能找到匹配查询语句的文档。这样遍历集合中整个文档的方式是很是耗时的,特别是处理大数据时,耗时几十秒甚至几分钟都是有可能的。sql
MongoDB 中,使用 ensureIndex() 方法建立索引。mongodb
格式数据库
db.COLLECTION_NAME.ensureIndex({KEY:1})
其中,KEY表示要建立索引的字段名称,1 表示按升序排列字段值。-1 表示按降序排列。ide
范例工具
一、给 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 会自动生成的索引名称。固然,咱们也能够本身指定索引的名称。ui
二、给 user 集合中 age 字段添加索引,并指定索引名称为 "index_age_esc"。spa
>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}) E11000 duplicate key error collection: liruihuan.user index: name_1 dup key: { : \"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(var i = 0; i <200000; i++){db.user.insert({"name":"lrh"+i,"age":18})}
第二步,删除 user 集合中字段 name 上的索引,而后查询 name = "lrh100000",利用explain("executionStats")查询此时执行的时间。说明:MongoDB explain() 方法在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" ...... } ....... } ....... } ...... }
业精于勤,荒于嬉;行成于思,毁于随。
若是你以为这篇文章不错或者对你有所帮助,能够经过右侧【打赏】功能,给予博主一点点鼓励和支持