MongoDB是一款基于文档的数据库,为了优化查询性能,提供了explain()
函数用于分析查询语句的执行情况。本文将详细介绍explain()
函数的作用和使用方法,并且提供两个实例进行说明。
1. 作用
explain()
函数的作用是分析查询语句的执行计划,输出查询过程中的详细信息,包括使用到的索引、扫描文档数、查询时间等,根据输出结果可以优化查询语句、修改索引等,以达到更好的查询性能。
2. 使用方法
explain()
函数可以直接在查询语句中使用,格式如下:
db.collection.find(query).explain([verbosity])
其中,query
表示查询条件,verbosity
表示输出详细程度,有三种:queryPlanner
、executionStats
和allPlansExecution
,默认是queryPlanner
。
实例1:
假设我们有一张students
表,包含了每个学生的姓名、年龄、成绩等信息,现在我们需要查询年龄大于20岁的学生列表,并且按照成绩从高到低排序。我们可以使用如下查询语句:
db.students.find({age: {$gt: 20}}).sort({score: -1}).limit(10)
输出结果如下:
{ "_id" : ObjectId("6161d87b9ed21bc1fee93c4e"), "name" : "小明", "age" : 25, "score" : 89 }
{ "_id" : ObjectId("6161d87b9ed21bc1fee93c4f"), "name" : "小红", "age" : 23, "score" : 88 }
...
我们也可以使用explain()
函数来分析该查询语句的执行计划:
db.students.find({age: {$gt: 20}}).sort({score: -1}).limit(10).explain("executionStats")
输出结果如下:
{
"executionStats" : {
"executionSuccess": true,
"nReturned": 10,
"executionTimeMillis": 0,
"totalKeysExamined": 10,
"totalDocsExamined": 10,
//......
},
//......
}
可以看出这条查询语句使用了executionStats
输出详细程度,执行过程中考虑了索引,扫描了10条文档,查询时间为0毫秒。
实例2:
假设我们有一张orders
表,包含了每个订单的时间、用户ID、订单状态等信息,我们想获取一个用户在过去7天内提交的所有订单,以及每个订单的详细信息。我们可以使用如下查询语句:
db.orders.aggregate([
{
$match: {
userid: "12234567",
orderdate: {$gte: new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000))}
}
},
{
$lookup: {
from: "orderdetails",
localField : "orderid",
foreignField : "orderid",
as : "orderdetails"
}
}
])
输出结果如下:
{ "_id" : ObjectId("6162279a9ed21bc1fee93c50"), "userid" : "12234567", "orderdate" : "2021-10-08", "orderid" : "10000002", "orderdetails" : [ { "_id" : ObjectId("616237629ed21bc1fee93c51"), "orderid" : "10000002", "productname" : "iPhone 13", "quantity" : 1, "price" : 7999 } ] }
{ "_id" : ObjectId("616227b69ed21bc1fee93c54"), "userid" : "12234567", "orderdate" : "2021-10-08", "orderid" : "10000005", "orderdetails" : [ { "_id" : ObjectId("616238ad9ed21bc1fee93c55"), "orderid" : "10000005", "productname" : "MacBook Pro", "quantity" : 1, "price" : 15999 } ] }
...
我们也可以使用explain()
函数来分析该查询语句的执行计划:
db.orders.aggregate([
{
$match: {
userid: "12234567",
orderdate: {$gte: new Date(new Date().getTime() - (7 * 24 * 60 * 60 * 1000))}
}
},
{
$lookup: {
from: "orderdetails",
localField : "orderid",
foreignField : "orderid",
as : "orderdetails"
}
}
]).explain("executionStats")
输出结果如下:
{
"stages" : [
{
"$cursor" : {
"query" : {
"userid" : "12234567",
"orderdate" : { "$gte" : ISODate("2021-10-04T11:09:00.818Z") }
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.orders",
"indexFilterSet" : false,
"parsedQuery" : {...},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {...}
"indexName" : "...",
"isMultiKey" : false,
"multiKeyPaths" : {...},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : {...},
"indexBounds" : {...}
}
},
"rejectedPlans" : [...]
}
}
},
{
"$lookup" : {
"from" : "orderdetails",
"localField" : "orderid",
"foreignField" : "orderid",
"as" : "orderdetails"
}
}
],
"serverInfo" : {...},
"ok" : 1,
//......
}
可以看出这条聚合语句使用了executionStats
输出详细程度,其中包括了查询优化器的工作过程,查询计划的选择、拒绝等信息。
3. 结论
通过explain()
函数能够更好的分析查询语句的执行计划,便于进行查询优化,通常在开发的过程中需要及时分析查询语句的执行计划,以达到更好的性能优化。