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"
                                 ......
                        }
                        .......
                 }
                .......
       }
       ......
}

 

業精於勤,荒於嬉;行成於思,毀於隨。

若是你以爲這篇文章不錯或者對你有所幫助,能夠經過右側【打賞】功能,給予博主一點點鼓勵和支持

相關文章
相關標籤/搜索