MongoDB的學習--explain()和hint()


Explain

從之前的文章中,我們可以知道explain()能夠提供大量與查詢相關的信息。對於速度比較慢的查詢來說,這是最重要的診斷工具之一。通過查看一個查詢的explain()輸出信息,可以知道查詢使用了哪個索引,以及是如何使用的。

最常見的explain()的輸出有兩種類型:使用索引的查詢和沒有使用索引的查詢。

在上一篇MongoDB的博客可以看到兩種類型的explain如下:

1. 沒有使用索引時

{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 1001,
    "nscanned" : 1001,
    "nscannedObjectsAllPlans" : 1001,
    "nscannedAllPlans" : 1001,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 7,
    "nChunkSkips" : 0,
    "millis" : 1,
    "server" : "user:27017",
    "filterSet" : false
}

2. 使用索引時

{
    "cursor" : "BtreeCursor username_1",
    "isMultiKey" : false,
    "n" : 1,
    "nscannedObjects" : 1,
    "nscanned" : 1,
    "nscannedObjectsAllPlans" : 1,
    "nscannedAllPlans" : 1,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "indexBounds" : {
        "username" : [
            [
                "user1000",
                "user1000"
            ]
        ]
    },
    "server" : "user:27017",
    "filterSet" : false
}

我們以有索引的結果為例,來依次看一下這些字段代表的意思

  • "cursor" : "BtreeCursor username_1"
    BtreeCursor表示本次查詢使用了索引,具體來說,是使用了“username”上的索引{“username”:1}。如果查詢要對結果進行逆序遍歷,或者使用了多鍵索引,就可以在這個字段中看到“reverse”和“multi”這樣的值。
  • "isMultiKey" : false
    用於說明本次是否使用了多鍵索引。
  • "n" : 1
    本次查詢返回的文檔數量
  • "nscannedObjects" : 1
    這是MongoDB按照索引指針去磁盤上查找實際文檔的次數。如果查詢包含的查詢條件不是索引的一部分,或者說要求返回不在索引內的字段,MongoDB就必須依次查找每個索引條目指向的文檔。
  • "nscanned" : 1
    如果有使用索引,那么這個數字就是查找過的索引條目數量,如果本次查詢是一次全表掃描,那么這個數字就代表檢查過的文檔數目。
  • "scanAndOrder" : false
    MongoDB是否在內存中對結果集進行了排序
  • "indexOnly" : false
    MongoDB是否只使用索引就能完成此次查詢。在本例中,MongoDB只使用索引就找到了全部的匹配文檔,從“nscanned”和“n”相等就可以看出來。然而,本次查詢要就返回匹配文檔中的所有字段,而索引只包含“username”這個字段,如果就本次查詢修改為{"_id":0, "username":1},那么本次查詢就可以被索引覆蓋了,"indexOnly"的值就會是true。
  • "nYields" : 0
    為了讓寫入請求能夠順利執行,本次查詢暫停暫停的次數。如果有寫入請求需求處理,查詢會周期性的釋放他們的鎖,以便寫入能夠順利執行。然而,在本次查詢中,沒有寫入請求,因此查詢沒有暫停過。
  • "millis" : 0
    數據庫執行本次查詢所耗費的毫秒數。這個數字越小,說明效率越高。
  • "indexBounds" : {...}
    這個字段描述了索引的使用情況,給出了索引的遍歷范圍。由於此次查詢是精確匹配,所以所以只要查“user1000”這個值就可以了。

Hint

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

db.users.find({"username":"user1000", "age":30}).hint({"username":1})

注意:請確定你已經創建了相應的索引。

假設在users上有個{"a": 1, "b": 1}的索引,名稱是"a_1_b_1",則如下兩種方式等價:

db.users.find({"a": 4, "b": 5, "c": 6}).hint({"a": 1, "b": 1})
db.users.find({"a": 4, "b": 5, "c": 6}).hint("a_1_b_1")

也可以強迫查詢不適用索引,做表掃描:

db.users.find().hint({"$natural":1})

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM