記錄下mongodb explain信息,使用的mongodb版本為4.0.9
項目關聯查詢了兩張表用户表與用户登錄日誌表,分別為user_info與user_login_info,腳本如下:
db.t_user_info.explain('allPlansExecution').aggregate([{
$lookup:{
from:"t_user_login_info",
localField:"userId",
foreignField:"userId",
as:"loginInfoList"
}
},
{
$match:{"userId":[10001725,154427587,10001747,10001749]}
}
])
結果:
{
"stages" : [
{
"$cursor" : {
"query" : {
"userId" : [
10001725.0,
154427587.0,
10001747.0,
10001749.0
]
},
"queryPlanner" : {
"plannerVersion" : 1.0,
"namespace" : "t_user_sync.t_user_info",
"indexFilterSet" : false,
"parsedQuery" : {//解析查詢條件
"userId" : {
"$eq" : [
10001725.0,
154427587.0,
10001747.0,
10001749.0
]
}
},
"winningPlan" : {//查詢優化器根據該query選擇的最優的查詢計劃
"stage" : "FETCH",//根據索引檢索指定的文檔
"filter" : {
"userId" : {
"$eq" : [
10001725.0,
154427587.0,
10001747.0,
10001749.0
]
}
},
"inputStage" : {
"stage" : "IXSCAN",//索引掃描
"keyPattern" : {//查詢命中的索引
"userId" : 1.0
},
"indexName" : "idx_user_id",//選擇的索引名
"isMultiKey" : false,//是否是複合索引,這裏不是所以是false
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2.0,
"direction" : "forward",//forward是升序,backward是降序
"indexBounds" : {//最優計劃所掃描的索引範圍
"userId" : [
"[10001725, 10001725]",
"[[ 10001725, 154427587, 10001747, 10001749 ], [ 10001725, 154427587, 10001747, 10001749 ]]"
]
}
}
},
"rejectedPlans" : [//其它計劃,因為不是最優計劃而被查詢優化器拒絕
]
},
"executionStats" : {
"executionSuccess" : true,//是否執行成功
"nReturned" : 0.0,//此query匹配到的文檔數
"executionTimeMillis" : 0.0,//查詢計劃選擇和查詢執行所需要的總時間,毫秒
"totalKeysExamined" : 2.0,//掃描的索引條目
"totalDocsExamined" : 1.0,//掃描的文檔數
"executionStages" : {//最優計劃完整信息
"stage" : "FETCH",//根據索引檢索指定的文檔
"filter" : {
"userId" : {
"$eq" : [
10001725.0,
154427587.0,
10001747.0,
10001749.0
]
}
},
"nReturned" : 0.0,
"executionTimeMillisEstimate" : 0.0,
"works" : 3.0,//指定查詢執行階段執行的工作單元的數量,查詢執行將其工作劃分為小單元
"advanced" : 0.0,//返回父階段的結果數
"needTime" : 2.0,//將中間結果返回給其父級的工作循環數
"needYield" : 0.0,//存儲層請求查詢系統產生鎖定的次數
"saveState" : 1.0,
"restoreState" : 1.0,
"isEOF" : 1.0,
"invalidates" : 0.0,
"docsExamined" : 1.0,
"alreadyHasObj" : 0.0,
"inputStage" : {//子執行單元,一個執行計劃中,可以有一個或多個inputStage
"stage" : "IXSCAN",//表示執行了索引掃描
"nReturned" : 1.0,
"executionTimeMillisEstimate" : 0.0,
"works" : 3.0,
"advanced" : 1.0,
"needTime" : 1.0,
"needYield" : 0.0,
"saveState" : 1.0,
"restoreState" : 1.0,
"isEOF" : 1.0,
"invalidates" : 0.0,
"keyPattern" : {
"userId" : 1.0
},
"indexName" : "idx_user_id",//查詢選中的索引名字
"isMultiKey" : false,//是否是複合索引
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2.0,
"direction" : "forward",//forward為升序,backward為降序
"indexBounds" : {//最優計劃所掃描的索引範圍
"userId" : [
"[10001725, 10001725]",
"[[ 10001725, 154427587, 10001747, 10001749 ], [ 10001725, 154427587, 10001747, 10001749 ]]"
]
},
"keysExamined" : 2.0,
"seeks" : 2.0,
"dupsTested" : 0.0,
"dupsDropped" : 0.0,
"seenInvalidated" : 0.0
}
},
"allPlansExecution" : [//不是最優計劃而被拒絕
]
}
}
},
{
"$lookup" : {
"from" : "t_user_login_info",
"as" : "loginInfoList",
"localField" : "userId",
"foreignField" : "userId"
}
}
],
"ok" : 1.0
}
explain有三種模式,分別為:
- queryPlanner(默認模式),該模式不會真正執行query語句查詢,查詢優化器根據查詢語句執行計劃分析出最優查詢計劃
- executionStats,該模式下查詢優化器會對當前的查詢進行評估且選擇一個最佳的查詢執行計劃,在執行完畢後返回這個最佳執行計劃執行完成時的相關統計信息
- allPlanExecution,該模式下包括上述2種模式的所有信息,即按照最佳的執行計劃以及列出統計信息,如果存在其它信息也會列出。
針對執行計劃我們需要重點關注stage字段
Stage參數説明
| 類型 | 描述 |
|---|---|
| COLLSCAN | 全表掃描 |
| IXSCAN | 索引掃描 |
| FETCH | 根據索引檢索指定的文檔 |
| SHARD_MERGE | 將各個分片的返回結果進行merge |
| SORT | 表示在內存中進行了排序 |
| LIMIT | 使用limit限制返回結果的數量 |
| SKIP | 使用skip進行跳過 |
| IDHACK | 針對_id進行查詢 |
| SHANDING_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返回 |
參考文章:MongoDB 中使用 explain 分析創建的索引是否合理