MongoDB基础教程系列--第六篇 MongoDB 索引

 返回目录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"
                                 ......
                        }
                        .......
                 }
                .......
       }
       ......
}

 

业精于勤,荒于嬉;行成于思,毁于随。

若是你以为这篇文章不错或者对你有所帮助,能够经过右侧【打赏】功能,给予博主一点点鼓励和支持

相关文章
相关标签/搜索