返回目錄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" ...... } ....... } ....... } ...... }
業精於勤,荒於嬉;行成於思,毀於隨。
若是你以爲這篇文章不錯或者對你有所幫助,能夠經過右側【打賞】功能,給予博主一點點鼓勵和支持