mongodb 執行計劃說明
建立documents:
for (i=0;i<1000000;i++){
db.users.insert(
{
"i":i,
"username":"user"+i,
"age":Math.floor(Math.random()*120),
"create":new Date()
}
);
}
建立索引:
db.users.createIndex({i:1},{background:1})
執行計劃:
mongodb 3 explain有三種模式
db.users.find({i:90000}).explain()
db.users.find({i:90000}).explain("queryPlanner") #explain的預設模式
db.users.find({i:90000}).explain("executionStats")
db.users.find({i:90000}).explain("allPlansExecution")
說明:
queryPlanner模式下並不會去真正進行query語句查詢,而是針對query語句進行執行計劃分析並選出winning plan。
repsetzhou:PRIMARY> db.users.find({i:9}).explain("queryPlanner")
{
"queryPlanner" : { #queryPlanner的返回
"plannerVersion" : 1,
"namespace" : "app_1.users", #該值返回的是該query所查詢的表
"indexFilterSet" : false, #針對該query是否有indexfilter
"parsedQuery" : {
"i" : {
"$eq" : 9
}
},
"winningPlan" : { #查詢優化器針對該query所返回的最優執行計劃的詳細內容
"stage" : "FETCH", #最優執行計劃的stage,這裡返回是FETCH,可以理解為通過返回的index位置去檢索具體的文件
"inputStage" : { # 用來描述子stage,並且為其父stage提供文件和索引關鍵字
"stage" : "IXSCAN", #queryPlanner.winningPlan.stage的child stage,此處是IXSCAN,表示進行的是index scanning
"keyPattern" : { #掃描的index內容,此處是 "i" : 1
"i" : 1
},
"indexName" : "i_1", #winning plan所選用的index,使用db.users.getIndexes() 檢視索引資訊
"isMultiKey" : false, #是否是Multikey,此處返回是false,如果索引建立在array上,此處將是true
"isUnique" : false, #是否為唯一鍵
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward", #query的查詢順序,此處是forward
"indexBounds" : {
"i" : [
"[9.0, 9.0]"
]
}
}
},
"rejectedPlans" : [ ] #其他執行計劃(非最優而被查詢優化器reject的)的詳細返回,具體資訊與winningPlan的返回中意義相同
},
"serverInfo" : { #server的一些資訊
"host" : "my1.ml.com", #主機名字
"port" : 27017, #資料庫埠
"version" : "3.2.13", #資料庫版本
"gitVersion" : "23899209cad60aaafe114f6aea6cb83025ff51bc"
},
"ok" : 1
}
executionStats分析:
repsetzhou:PRIMARY> db.users.find({i:9}).explain("executionStats")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "app_1.users",
"indexFilterSet" : false,
"parsedQuery" : {
"i" : {
"$eq" : 9
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"i" : 1
},
"indexName" : "i_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"i" : [
"[9.0, 9.0]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 1, #查詢返回的條目
"executionTimeMillis" : 0, #該query的整體查詢時間
"totalKeysExamined" : 1, #索引掃描條目
"totalDocsExamined" : 1, #文件掃描條目
對於一個查詢來講,最理想的結果是:nReturned=totalKeysExamined=totalDocsExamined
"executionStages" : {
"stage" : "FETCH", #此型別比較重要,如下列出可能的型別:
stage的型別:
COLLSCAN:全表掃描
IXSCAN:索引掃描
FETCH:根據索引去檢索指定document
SHARD_MERGE:將各個分片返回資料進行merge
SORT:表明在記憶體中進行了排序
LIMIT:使用limit限制返回數
SKIP:使用skip進行跳過
IDHACK:針對_id進行查詢
SHARDING_FILTER:通過mongos對分片資料進行查詢
COUNT:利用db.coll.explain().count()之類進行count運算
COUNTSCAN:count不使用Index進行count時的stage返回
COUNT_SCAN:count使用了Index進行count時的stage返回
SUBPLA:未使用到索引的$or查詢的stage返回
TEXT:使用全文索引進行查詢時候的stage返回
PROJECTION:限定返回欄位時候stage的返回
對於普通查詢,我希望看到stage的組合(查詢的時候儘可能用上索引):
Fetch+IDHACK
Fetch+ixscan
Limit+(Fetch+ixscan)
PROJECTION+ixscan
SHARDING_FITER+ixscan
COUNT_SCAN
如下的stage效率比較低下:
COLLSCAN(全表掃描),SORT(使用sort但是無index),不合理的SKIP,SUBPLA(未用到index的$or),COUNTSCAN(不使用index進行count)
"nReturned" : 1,
"executionTimeMillisEstimate" : 0, #該query查詢根據index去檢索document獲得1條資料的時間
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 1,
"executionTimeMillisEstimate" : 0, #該查詢掃描1行index所用時間
"works" : 2,
"advanced" : 1,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"i" : 1
},
"indexName" : "i_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"i" : [
"[9.0, 9.0]"
]
},
"keysExamined" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
}
},
"serverInfo" : {
"host" : "my1.ml.com",
"port" : 27017,
"version" : "3.2.13",
"gitVersion" : "23899209cad60aaafe114f6aea6cb83025ff51bc"
},
"ok" : 1
}