使用explain获取分析信息
官方提供了db.collection.explain()方法获取执行语句的分析数据。
以下例子:
// find
db.getCollection('user').find({}).explain();
// aggregate
db.getCollection('user').explain().aggregate([]);
explain有三种模式,
- queryPlanner Mode (默认)
- executionStats Mode
- allPlansExecution Mode
使用不通模式的例子:
# 只需要在执行explain函数时输入不通的值即可
// executionStats
db.getCollection('user').find({}).explain('executionStats');
db.getCollection('user').find({}).explain('allPlansExecution');
// allPlansExecution
db.getCollection('user').explain('executionStats').aggregate([]);
db.getCollection('user').explain('allPlansExecution').aggregate([]);
explain默认不会执行实际的语句,只会通过引擎分析返回实际将如何执行,如果需要返回实际执行的数据,则需要使用executionStats模式。
三个模式是逐渐增强的关系。
使用queryPlanner只列出所有可能执行的方案,已经胜出的方案winningPlan。
使用executionStats只执行winningPlan方案,并输出结果。
使用allPlansExecution执行所有的方案,并输出结果。
获取具体的分析指标
通常分析一个查询,Operation Execution Time指标只是最终结果,也就是执行慢。 慢的因数总结为以下几点:
- 扫描过多的文档
- 没有命中索引,导致需要扫描大量的数据才能找到想要的数据
- 查询条件过大
- 返回过多的数据
- 没有限制返回数量
- 没有限制返回字段
通过executionStats获取执行分析数据
这是一个实例数据,为了方便阅读只保留部分有用的信息
{
"stages" : [
{
"$cursor" : {
...
"queryPlanner" : {
...
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "SORT_MERGE",
"sortPattern" : {
...
},
"inputStages" : [
...
]
}
},
"rejectedPlans" : [
...
]
},
// 执行结果
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 20,
"executionTimeMillis" : 8,
"totalKeysExamined" : 102,
"totalDocsExamined" : 101,
"executionStages" : {
...
}
}
}
}
],
...
}
在结果中,executionStats中的信息提供几个有用的信息:
nReturned 返回文档数
executionTimeMillis 执行时间
totalKeysExamined 总扫描数
totalDocsExamined 总扫描文档数
通过这几个属性大致可以判断出有没有当前查询语句是否有性能问题。
MongoDB常见分析指标
- Operation Execution Time,执行耗时,越小越好。
- Keys Examined,扫描文档数,越小越好。
- Docs Returned,返回文档数,需要保持在一个合理的值。
- Examined:Returned Ratio,扫描文档数和返回文档书比例,越大越好(在控制返回文档数的前提)。
- Num Yields
- Response Length,返回大小,需要保持在一个合理的值。
- Used An Index,是否命中索引,命中索引好。
- In Memory Sort,内存排序,不在内存排序好。
参考文档
Query Profiler — MongoDB Atlas
db.collection.explain() — MongoDB Manual
Explain Results — MongoDB Manual