查看执行计划
索引优化是一个永远都绕不过的话题,作为NoSQL的MongoDB也不例外。Mysql中通过explain命令来查看对应的索引信息,MongoDB亦如此。
1. db.collection.explain().<method(...)>
db.products.explain().remove( { category: "apparel" }, { justOne: true })
2. db.collection.<method(...)>.explain({})
db.products.remove( { category: "apparel" }, { justOne: true }).explain()
如果你是在mongoshell 中第一种和第二种没什么区别,如果你是在robot 3T这样的客户端工具中使用你必须在后面显示调用finish()或者next()
db.collection.explain().find({}).finish()
explain有三种模式,分别是:
- queryPlanner(默认) :queryPlanner模式下并不会去真正进行query语句查询,而是针对query语句进行执行计划分析并选出winning plan
- executionStats :MongoDB运行查询优化器以选择获胜计划(winning plan),执行获胜计划直至完成,并返回描述获胜计划执行情况的统计信息。
- allPlansExecution: queryPlanner和executionStats都返回。相当于
explain("allPlansExecution") = explain({})
queryPlanner(查询计划)
日志表中存储了用户的操作日志,我们经常查询某一篇文章的操作日志,数据如下:
{
"_id" : NumberLong(7277744),
"operatorName" : "autotest_cp",
"operateTimeUnix" : NumberLong(1586511800890),
"module" : "ARTICLE",
"opType" : "CREATE",
"level" : "GENERAL",
"recordData" : {
"articleId" : "6153324",
"categories" : "100006",
"title" : "testCase-2 this article is created for cp edior to search",
"status" : "DRAFT"
},
"responseCode" : 10002
}
集合中大概有700万数据,对于这样的查询语句
db.getCollection('operateLog').find({"module": "ARTICLE", "recordData.articleId": "6153324"}).sort({_id:-1})
首先看下queryPlanner返回的内容:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "smcp.operateLog",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"module" : {
"$eq" : "ARTICLE"
}
},
{
"recordData.articleId" : {
"$eq" : "6153324"
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"$and" : [
{
"module" : {
"$eq" : "ARTICLE"
}
},
{
"recordData.articleId" : {
"$eq" : "6153324"