MongoDB性能分析和優化2(hint演示)

雖然MongoDB查詢優化器一般工作的很不錯,但是也可以使用 hint 來強制 MongoDB 使用一個指定的索引。
這種方法某些情形下會提升性能。 一個有索引的 collection 並且執行一個多字段的查詢(一些字段已經索引了)。

(1) 複合索引創建語法
db.collection.createIndex( { : , : , … } )
同創建單鍵(列)索引一樣,索引創建時需要指定每一個鍵索引的順序
多個鍵直接用逗號分隔

(2) 複合索引的特性
1.複合索引可以支持要求匹配多個鍵的查詢
2.複合索引每一個鍵的順序非常重要,這將決定該索引在查詢過程中能否被使用到
3.複合索引支持前導(綴)列索引查詢
4.不能夠創建基於哈希索引類型的複合索引
5.任意複合索引字段不能超過31個

(3) 索引性能對比
你可以使用 hint() 方法結合 explain() 方法來對查詢中的多個索引的性能進行手工對比。

在使用複合索引的時候,字段的順序很重要(注意是索引中的順序,而非查詢中出現的順序)。
比如,創建下面兩個複合索引。第一個索引把 quantity 字段放在前面,而第二個字段把 type 字段放前:
爲了方便演示,我們做兩組複合索引,比如這次我們在quality和type上構建一下:
在這裏插入圖片描述
針對quantity是一個範圍,而type是一個定值的情況下,我們強制mongodb去使用quantity開頭的複合索引,從而強制mongodb give up 那個以{type:1,quantity:1}的複合索引,如下圖:
在這裏插入圖片描述
上圖中,可以看到MongoDB掃描了6個索引鍵(executionStats.totalKeysExamined)以及2個匹配文檔(executionStats.nReturned)。

再對第二個索引在該查詢上的效果進行評估:
在這裏插入圖片描述
MongoDB 掃描了 2 個索引鍵(executionStats.totalKeysExamined)以返回 2 個匹配的文檔(executionStats.nReturned)。
顯而易見,對於上述查詢,複合索引 { type: 1, quantity: 1 } 比 { quantity: 1, type: 1 } 更高效。

indexBounds:當前查詢具體使用的索引。
分析index與document掃描數與查詢返回條目數
這裏主要談3個返回項,nReturned,totalKeysExamined與totalDocsExamined,分別代表該條查詢返回的條目、索引掃描條目和文檔掃描條目。
理想狀態如下:
nReturned=totalKeysExamined & totalDocsExamined=0 (cover index,僅僅使用到了index,無需文檔掃描,這是最理想狀態。)
或者
nReturned=totalKeysExamined=totalDocsExamined(需要具體情況具體分析)(正常index利用,無多餘index掃描與文檔掃描。)檢查的鍵數與返回的文檔數相匹配,這意味着mongod只需檢查索引鍵即可返回結果。mongod不必掃描所有文檔,只有三個匹配的文檔被拉入內存。 這個查詢結果是非常高效的。
如果有sort的時候,爲了使得sort不在內存中進行,我們可以在保證nReturned=totalDocsExamined的基礎上,totalKeysExamined可以大於totalDocsExamined與nReturned,因爲量級較大的時候內存排序非常消耗性能。

如果查詢條件中的鍵值順序和複合索引中的創建順序不一致的話,MongoDB可以智能的幫助我們調整該順序,以便使複合索引可以爲查詢所用
MongoDB在檢索之前將會動態的調整查詢條件文檔的順序,以使該查詢可以用到剛剛創建的複合索引
hint函數會返回遊標,我們可以在遊標上調用explain查看索引的使用情況!99%的情況,我們沒有必要通過hint去強制使用某個索引,MongoDB的查詢優化器非常智能,絕對能幫助我們使用當前已有索引中的最佳的索引去進行查詢!
通過hint去強制使用某個索引這種方法某些情形下會提升性能。 一個有索引的 collection 並且執行一個多字段的查詢(一些字段已經索引了)可以用。

>db.users.find({gender:"M"},{user_name:1,_id:0}).hint({gender:1,user_name:1})

文檔連接:http://www.runoob.com/mongodb/mongodb-analyzing-queries.html

API原文鏈接:https://docs.mongodb.com/manual/tutorial/analyze-query-plan/

(4) 何時該用索引
提取較小的子數據集時,索引非常有效(所以纔有了分頁)。也有一些查詢不使用索引會更快。結果集在原集合中所佔的比例越大,查詢效率越慢。因爲使用索引需要進行兩次查找:一次查找索引條目,一次根據索引指針去查找相應的文檔。而全表掃描只需要進行一次查詢。在最壞的情況,使用索引進行查找次數會是全表掃描的兩倍。效率會明顯比全表掃描低。
可惜並沒有一個嚴格的規則可以告訴我們,如果根據索引大小、文檔大小來判斷什麼時候索引很有用,一般來說,如果查詢需要返回集合內30%的文檔(或者更多),那就應該測試全表掃描和走索引查詢那個速度比較快。這個數字也會在2%~60%之間進行波動。
這個時候可以使用hint({"$natural":true})強制查詢走全表掃描。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章