MongoDb學習之Explain執行計劃

小勇勇發表於2021-12-14

mongodb 3.0和之前版本的explain執行計劃有非常巨大的差距,這裡只學習介紹3.0以後的用法

支援檢視以下幾種操作的執行計劃

基本的使用方式

db.collection.find().explain(verbose)

verboseexplain執行計劃的輸出模式有以下三種

  • queryPlanner

這是explain的預設輸出方式

包含執行計劃的基本詳情資訊,包含:查詢計劃、集合資訊、查詢條件、最佳執行計劃、查詢方式和mongodb的基礎資訊

  • executionStats

這種輸出方式會在queryPlanner的基礎上輸出最佳執行計劃的一些統計資訊

  • allPlansExecution

獲取所有的執行計劃,也就是把集合中所有的每一種索引都生成一個執行計劃內容,給與使用者判斷

詳解explain欄位

樣例

下面是allPlansExecution模式下輸出的執行計劃,也包含了其它兩種模式會輸出的內容

{
  "queryPlanner":{
    "plannerVersion":1,
    "namespace":"mock.users",
    "indexFilterSet":false,
    "parsedQuery":{
      "age":{
        "$gte":10
      }
    },
    "winningPlan":{
      "stage":"FETCH",
      "inputStage":{
        "stage":"IXSCAN",
        "keyPattern":{
          "age":1,
          "username":1
        },
        "indexName":"age_1_username_1",
        "isMultiKey":false,
        "multiKeyPaths":{
          "age":[
          ],
          "username":[
          ]
        },
        "isUnique":false,
        "isSparse":false,
        "isPartial":false,
        "indexVersion":2,
        "direction":"forward",
        "indexBounds":{
          "age":[
            "[10, inf.0]"
          ],
          "username":[
            "[MinKey, MaxKey]"
          ]
        }
      }
    },
    "rejectedPlans":[
      {
        "stage":"FETCH",
        "inputStage":{
          "stage":"IXSCAN",
          "keyPattern":{
            "age":1
          },
          "indexName":"age_1",
          "isMultiKey":false,
          "multiKeyPaths":{
            "age":[
            ]
          },
          "isUnique":false,
          "isSparse":false,
          "isPartial":false,
          "indexVersion":2,
          "direction":"forward",
          "indexBounds":{
            "age":[
              "[10, inf.0]"
            ]
          }
        }
      }
    ]
  },
  "executionStats":{   --這個集合是executionStats&allPlansExecution模式才有的
    "executionSuccess":true,
    "nReturned":680520,
    "executionTimeMillis":1121,
    "totalKeysExamined":680520,
    "totalDocsExamined":680520,
    "executionStages":{
      "stage":"FETCH",
      "nReturned":680520,
      "executionTimeMillisEstimate":143,
      "works":680521,
      "advanced":680520,
      "needTime":0,
      "needYield":0,
      "saveState":680,
      "restoreState":680,
      "isEOF":1,
      "docsExamined":680520,
      "alreadyHasObj":0,
      "inputStage":{
        "stage":"IXSCAN",
        "nReturned":680520,
        "executionTimeMillisEstimate":43,
        "works":680521,
        "advanced":680520,
        "needTime":0,
        "needYield":0,
        "saveState":680,
        "restoreState":680,
        "isEOF":1,
        "keyPattern":{
          "age":1,
          "username":1
        },
        "indexName":"age_1_username_1",
        "isMultiKey":false,
        "multiKeyPaths":{
          "age":[
          ],
          "username":[
          ]
        },
        "isUnique":false,
        "isSparse":false,
        "isPartial":false,
        "indexVersion":2,
        "direction":"forward",
        "indexBounds":{
          "age":[
            "[10, inf.0]"
          ],
          "username":[
            "[MinKey, MaxKey]"
          ]
        },
        "keysExamined":680520,
        "seeks":1,
        "dupsTested":0,
        "dupsDropped":0
      }
    },
    "allPlansExecution":[  --這是allPlansExecution執行才會有的返回集合
      {
        "nReturned":101,
        "executionTimeMillisEstimate":0,
        "totalKeysExamined":101,
        "totalDocsExamined":101,
        "executionStages":{
          .......
        }
      }
    ]
  },
  "serverInfo":{
    "host":"supman",
    "port":27017,
    "version":"4.4.10",
    "gitVersion":"58971da1ef93435a9f62bf4708a81713def6e88c"
  },
  "ok":1
}

詳解

  • queryPlanner

    • plannerVersion 執行計劃版本
    • namespace 查詢的集合
    • indexFilterSet 是否使用了索引過濾器(網上搜好多說是 是否使用了索引 很坑爹)
    • parsedQuery 查詢條件
    • winningPlan 最佳執行計劃
    • stage 查詢方式

      狀態描述
      COLLSCAN全表掃描
      IXSCAN索引掃描
      FETCH根據索引檢索指定文件
      SHARD_MERGE將各個分片返回資料進行合併
      SORT在記憶體中進行了排序
      LIMIT使用limit限制返回數
      SKIP使用skip進行跳過
      IDHACK對_id進行查詢
      SHARDING_FILTER通過mongos對分片資料進行查詢
      COUNTSCANcount不使用Index進行count時的stage返回
      COUNT_SCANcount使用了Index進行count時的stage返回
      SUBPLA未使用到索引的$or查詢的stage返回
      TEXT使用全文索引進行查詢時候的stage返回
      PROJECTION限定返回欄位時候stage的返回
    • inputStage 用來描述子stage,並且為其父stage提供文件和索引關鍵字,這裡面含有著執行計劃中比較主要的資訊

      • statge
      • keyPattern掃描的索引的內容
      • indexName 索引名稱
      • isMultiKey 是否是索引陣列,即索引建立在陣列上則為true`
      • `MultiKeyPath 若索引建立在陣列上,顯示索引的欄位
      • isUnique 是否為唯一索引,這種索引所在的屬性的每個值必須都是唯一不重複的,而且在建立時需要指明這是一個唯一索引

        db.users.createIndex({"username":1},{unique:true"})
      • isSparse 是否為稀疏索引,這種索引上面的欄位可以不存在,一般用於可選欄位建立的索引,比如說email這種在個人資訊中可填可不填的欄位,同樣這種索引在建立的時候也需要指定

        db.users.createIndex({"email":1},{sparse:true"})
      • isPartial 是否為部分索引,這種索引只為滿足篩選條件的資料建立索引

        db.users.createIndex({age:1},{partialFilterExpression:{age:{"$gte":25}}})

        如上,這種索引只在查詢條件為age ≥ 25的時候生效

      • direction 這裡代表查詢順序,有兩種情況forward或者backward,現在建立一個{age:1}索引

        db.users.find().sort()         --這種情況是forward
        db.users.find().sort({age:-1}) --這種情況是backward
      • indexVersion 索引版本
      • indexBounds 所掃描的索引範圍,例如indexBounds: { age: [ '[36, 38]' ] } } }就是代表掃描[36,38]這個區間的age欄位的索引
      • rejectedPlans 拒絕計劃,非最優的執行計劃,它的欄位與winningPlan一樣不再描述

        • .......
    • serverInfo MongoDB伺服器資訊

      • host 主機名稱
      • port
      • version 服務版本
      • gitVersion git版本號
    • executionStats 包含一些統計資訊

      • executionSuccesss 是否執行成
      • nReturned 表示返回的行數
      • executionTimeMillis 執行耗時,單位毫秒
      • totalKeysExamined 索引掃描次數
      • totalDocsExamined 文件掃描次數
      • executionStages 成功的計劃詳情,下面的很多欄位在上面已經陳述過了,在這裡就不再寫了
      • works 工作單元數,一個查詢會分解成很多小的查詢單元
      • advanced 優先返回的結果數
      • needTime 未將中間結果推進到其父級的工作週期數
      • needYield 儲存層查詢產生鎖的次數
      • isEOF 指定執行階段是否達到流結束
      • ......
      • inputStage

        • seeks 為了完成索引掃描(stage),執行器必須將遊標定位到新位置的次數
        • ......
    • allPlansExecution 含有所有執行計劃

      • .......

撒花結束

哈哈,終於搞完了還有幾個欄位沒有搞清楚dupsTestedsaveState,不過有了上面這些內容對整個執行計劃的基本拿捏肯定不成問題

相關文章