天天看點

mongodb 查詢效率_MongoDB 存儲和優化系列三

上篇文章我們介紹了索引的基本概念,描述了不同類型索引的差別,工欲善其事,必先利其器,這篇文章,我們将展開介紹 explain 這個執行計劃函數,進一步的了解Mongo的查詢計劃,來分析和診斷,提高查詢的效率。

explain()

是MongoDB的一個重要的查詢診斷工具,這個函數能夠提供大量與查詢相關的資訊,該函數會傳回查詢計劃、執行狀态、伺服器資訊,根據這些資訊可以有針對性的對性能進行優化。

  • explain()函數
  • explain() 傳回資訊
  • explain() 使用示例
cursor.explain(verbosity)
  • verbose

    :{String},可選參數。指定冗長模式的解釋輸出,方式指定後會影響

    explain()

    的行為及輸出資訊。可選值有:

    "queryPlanner"

    "executionStats"

    "allPlansExecution"

    ,預設為

    "queryPlanner"

explain()傳回資訊

queryPlanner 包括以下值:

  1. queryPlanner.namespace「運作查詢的指定命名空間」
  2. queryPlanner.indexFilterSet「表示MongoDB在查詢中是否使用索引過濾」
  3. queryPlanner.winningPlan「由查詢優化選擇的計劃」

winningPlan.stage「表示查詢階段的字元串」

winningPlan.inputStage「表示子過程的文檔」

winningPlan.inputStages「表示子過程的文檔數組」

queryPlanner.rejectedPlans「被查詢優化備選并被拒絕的計劃數組」

executionStats「被選中執行計劃和被拒絕執行計劃的詳細說明」

queryPlanner.nReturned「比對查詢條件的文檔數」

queryPlanner.executionTimeMillis「計劃選擇和查詢執行所需的總時間(毫秒數)」

queryPlanner.totalKeysExamined「掃描的索引總數」

queryPlanner.totalDocsExamined「掃描的文檔總數」

queryPlanner.executionStages「顯示執行成功細節的查詢階段樹」

executionStages.works「指定查詢執行階段執行的“工作單元”的數量」

executionStages.advanced「傳回的中間結果數」

executionStages.needTime「未将中間結果推進到其父級的工作周期數」

executionStages.needYield「存儲層要求查詢系統産生的鎖的次數」

executionStages.isEOF「指定執行階段是否已到達流結束」

queryPlanner.allPlansExecution「包含在計劃選擇階段期間捕獲的部分,包括選擇計劃和拒絕計劃」

serverInfo:「MongoDB執行個體的相關資訊」

winningPlan.shards「包括每個通路片的queryPlanner和serverInfo的文檔數組」

下圖展示如何選擇查詢計劃

mongodb 查詢效率_MongoDB 存儲和優化系列三

執行 db.persons.find({age:10}).explain("executionStats")我們看具體的explain計劃

/* 1 */
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "Performance.persons", --資料庫名+集合的名稱
        "indexFilterSet" : false,
        "parsedQuery" : {
            "age" : {
                "$eq" : 10.0 -- 生成原生的查詢 {age:10}
            }
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "age" : 1.0,
                    "name" : 1.0
                },
                "indexName" : "age_1_name_1",
                "isMultiKey" : false, -- 多Key索引
                "multiKeyPaths" : { -- 複合索引的Key Path 
                    "age" : [],
                    "name" : []
                },
                "isUnique" : false, -- 唯一索引
                "isSparse" : false, -- 稀疏索引
                "isPartial" : false, -- 部分索引
                "indexVersion" : 2,
                "direction" : "forward", 
                "indexBounds" : { -- 索引的查詢範圍
                    "age" : [ 
                        "[10.0, 10.0]"
                    ],
                    "name" : [ 
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : []
    },
    "executionStats" : { -- 執行計劃的統計
        "executionSuccess" : true,
        "nReturned" : 2, -- 查詢得到的文檔數目
        "executionTimeMillis" : 2, -- 查詢消耗的毫秒數
        "totalKeysExamined" : 2, -- 索引掃描的數量
        "totalDocsExamined" : 2, -- 文檔掃描的數量
        "executionStages" : {
            "stage" : "FETCH",
            "nReturned" : 2,
            "executionTimeMillisEstimate" : 0,
            "works" : 3, -- 工作單元
            "advanced" : 2, --傳回的中間數
            "needTime" : 0,
            "needYield" : 0,
            "saveState" : 0,
            "restoreState" : 0,
            "isEOF" : 1, -- 遊标的末尾
            "invalidates" : 0,
            "docsExamined" : 2,
            "alreadyHasObj" : 0,
            "inputStage" : {
                "stage" : "IXSCAN",
                "nReturned" : 2,
                "executionTimeMillisEstimate" : 0,
                "works" : 3,
                "advanced" : 2,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "keyPattern" : {
                    "age" : 1.0,
                    "name" : 1.0
                },
                "indexName" : "age_1_name_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "age" : [],
                    "name" : []
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "age" : [ 
                        "[10.0, 10.0]"
                    ],
                    "name" : [ 
                        "[MinKey, MaxKey]"
                    ]
                },
                "keysExamined" : 2,
                "seeks" : 1,
                "dupsTested" : 0,
                "dupsDropped" : 0,
                "seenInvalidated" : 0
            }
        }
    },
    "serverInfo" : { -- server information
        "host" : "bogon",
        "port" : 27017,
        "version" : "4.0.3",
        "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
    },
    "ok" : 1.0
}           

基礎知識準備的差不多了,下一篇我們将就慢查詢優化,展開讨論,讓我們一起來見證奇迹的發生.........

參考文章

Query Plans - MongoDB Manual​docs.mongodb.com

mongodb 查詢效率_MongoDB 存儲和優化系列三

planCacheListFilters - MongoDB Manual​docs.mongodb.com

mongodb 查詢效率_MongoDB 存儲和優化系列三

planCacheClearFilters - MongoDB Manual​docs.mongodb.com

mongodb 查詢效率_MongoDB 存儲和優化系列三

planCacheSetFilter - MongoDB Manual​docs.mongodb.com

mongodb 查詢效率_MongoDB 存儲和優化系列三

cursor.hint() - MongoDB Manual​docs.mongodb.com

mongodb 查詢效率_MongoDB 存儲和優化系列三

Explain Results - MongoDB Manual​docs.mongodb.com

mongodb 查詢效率_MongoDB 存儲和優化系列三

Glossary - MongoDB Manual​docs.mongodb.com

mongodb 查詢效率_MongoDB 存儲和優化系列三

https://docs.mongodb.com/manual/reference/method/db.collection.update/#db.collection.update​docs.mongodb.com