MongoDB索引調優(2)

2021-08-20 18:40:28 字數 3419 閱讀 2704

可以在巢狀文件的鍵上建立索引,方式與正常的鍵一樣。如果有這樣乙個集合,如下所示:

js**  

db.emp.insert(,  

"age":25  

})  

現在我要在內嵌文件的first鍵上建立索引?如下所示

js**  

> db.emp.ensureindex()  

js**  

db.blog.insert(,  

,  ,  

]  })  

如果要找出comments.score大於5的所有文章,可以在comments.score鍵上面建立索引:

js**  

> db.blog.ensureindex()  

對陣列建立索引需要注意   

在陣列上建立的索引並不包含任何位置資訊:無法使用陣列索引查詢特定位置的陣列元素,比如"comments.4".

乙個索引中陣列欄位最多只能有乙個。這是為了避免在復合索引中索引條目**性增長。

對於某個索引的鍵,如果這個鍵在某個文件中是乙個陣列,那麼這個索引就會標記為多鍵索引。可以從explain()的輸出資訊中看到乙個索引是否為多鍵索引。如果是多鍵索引,那麼"ismultikey"欄位的值就會為true。索引只要被標記為多鍵索引,就無法再變成非多鍵索引,即使索引的鍵從文件中刪除也不行。唯一的辦法就是刪除重建。

explian()能夠提供大量與查詢相關的資訊。對於速度比較慢的查詢來說,這是最重要的診斷工具。通過檢視explian()的輸出資訊,可以知道查詢使用了那個索引,以及如果使用他的。對於任意查詢來,都可以在最後新增乙個explain()呼叫,但是呼叫explain()的時間必須是最後。

參考例項:

js**  

> db.users.find(}).sort().limit(100).explain()  

,    

]  ]  

},  

"server" : "localhost.localdomain:27017",  

"filterset" : false

}explain()輸出各個資訊的含義如下表所示

"cursor" : "btreecursor age_1_name_1"

表示本次查詢使用了索引,具體使用了age_1_name_1這個索引

"ismultikey" : false

用於說明本次查詢是否使用了多鍵索引

"n" : 100

本次查詢返回的文件數量

"nscannedobjects" : 100

這是mongodb使用索引指標去磁碟上查詢文件的實際次數

"nscanned" : 100

如果有使用索引,那麼這個數字就是檢查過的索引個數,如果本次查詢是全表掃瞄,那麼這個數字就是檢查過的文件個數

"scanandorder" : false

mongodb是否在記憶體中對結果集進行了排序

"indexonly" : false

mongodb是否只使用索引就可以完成本次查詢("覆蓋索引")

"nyields" : 0

為了讓寫入請求能夠順利執行,本次查詢暫停的次數。如果有寫入請求需要處理,查詢會周期性地釋放他的鎖,以便寫人能夠順利執行。然而,在本次查詢中沒有寫入請求,因為查詢沒有暫停過。

"millis" : 0

資料庫執行本次查詢所耗費的毫秒數。這個數字越小,說明查詢效率越高

indexbounds:

這個字段描述了索引的使用情況,給出了索引的遍歷範圍。因為本次查詢只使用了age做為查詢條件跟排序條件,沒有指定第二個鍵,因此在name鍵上沒有限制,資料庫會把使用者名稱介於負無窮("$minelement" : 1)到正無窮("$maxelement" : 1)之間進行搜尋

hint()方法用於讓mongodb強制使用某個索引,或者查詢使用了索引反而效率更低,這個時候可以使用hint()遮蔽索引讓查詢走全表掃瞄。

參考例項:強制本次查詢使用這個索引

js**  

> db.users.find(}).sort().hint().explain()  

參考例項:強制本次查詢走全表掃瞄

js**  

> db.users.find(}).sort().hint().explain()--使用--$"font-size: 1em; line-height: 1.5;">natural

"font-size: 1em; line-height: 1.5;"> 強制全表掃瞄

"$where"和"$exists":這兩個操作符,完全不能使用索引。

"$ne":通常來說取反的效率比較低。"$ne"查詢可以使用索引,但並不是很有效。因為他必須檢視所有的索引條目,而不是"$ne"指定的條目,這個時候他就不得不掃瞄整個索引。

"$not":有時候能夠使用索引,但是他通常並不知道要如何使用索引。所以大多數情況"$not"會退化為全表掃瞄。

"$nin":這個操作符總是會全表掃瞄

mongodb在一次查詢中只能使用乙個索引(至少我現在用的2.6是這樣的),如果你在上有乙個索引,在上也有乙個索引,在上執行查詢時,mongodb只會使用其中乙個索引,而不是兩個一起使用。"$or"是乙個例外,"$or"可以對每個字句都使用索引,因為"$or"實際上是執行兩次查詢然後將結果合併。

通常來說,使用or查詢多次在合併結果,不如單次查詢的效率高,對於單個字段,應該盡可能使用$in。

mongodb的查詢優化器與其他資料庫的稍微不同。基本來說,如果乙個索引能夠精確匹配乙個查詢,那麼查詢優化器就會使用這個索引,如果不能精確匹配,可能會有幾個索引都適合你的查詢。那mongodb是怎樣選擇的呢?答:mongodb的查詢計畫會將多個索引並行的去執行,最早返回100個結果的就是勝者,其他查詢計畫都會被終止。

這個查詢計畫會被緩衝,接下來的這個查詢都會使用他,下面幾種情況會重新計畫;

最初的計畫評估之後集合發生了比較大的資料波動,查詢優化器就會重新挑選可行的查詢計畫。

建立索引時。

每執行1000次查詢之後,查詢優化器就會重新評估查詢計畫

提取較小的子資料集時,索引非常有效(所以才有了分頁)。也有一些查詢不使用索引會更快。結果集在原集合中所佔的比例越大,查詢效率越慢。因為使用索引需要進行兩次查詢:一次查詢索引條目,一次根據索引指標去查詢相應的文件。而全表掃瞄只需要進行一次查詢。在最壞的情況,使用索引進行查詢次數會是全表掃瞄的兩倍。效率會明顯比全表掃瞄低。

可惜並沒有乙個嚴格的規則可以告訴我們,如果根據索引大小、文件大小來判斷什麼時候索引很有用,一般來說,如果查詢需要返回集合內30%的文件(或者更多),那就應該測試全表掃瞄和走索引查詢那個速度比較快。這個數字也會在2%~60%之間進行波動。

這個時候可以使用hint()強制查詢走全表掃瞄。

Mongodb效能調優

摘要 1.mongodb 適用場景簡介 2.mongodb 效能監控與分析 3.mongodb 效能優化建議 關於mongodb的幾個大事件 1.根據美國資料庫知識大全官網發布的db熱度排行,mongodb的熱度排名從2014年的第5名,在2015年躍公升為第4名,僅次於主流db oracle my...

資料庫調優 2 索引

一 建立索引技巧 應該選擇資料量大的表。應該選擇使用頻繁的字段上建立索引,如經常查詢的字段,排序的字段,用於where子句作為條件判斷的字段。經常用在連線的列。應該選擇重複值較小的字段上建立所以,例如使用者表 應該在使用者id上建立索引,而不是使用者的位址如省份或者性別。當修改效能遠遠大於檢索效能時...

SQL調優(索引)

索引 主鍵索引,唯一索引,組合索引,全文索引等 sql優化步驟 首先定位慢查詢 mqsql預設是響應超過十秒鐘的才是慢查詢 定位到了慢查詢才根據語句看採用什麼調優方式 索引的實現原理其實就是二叉樹 b 樹 主鍵索引 當我們在習慣性的生成primiry key的時候,就是生成了主鍵索引,採用二叉樹的形...