问题描述
我正在尝试使用有关公司简介保证金的数据集的MongoDB,以进行学习。这是示例文档
{
"parent_comp" : 1
"child_comp" : 101
"profit" : NumberLong(70320020)
}
我创建了两个索引,即一个在child_comp字段上,另一个是具有parent_comp,child_comp和last_outage_timestamp的复合索引。
对于以下查询,我执行了 explain 命令以查看查询计划。
MongoDB Enterprise > db.data.find({ "$and" : [{ "parent_comp" : 951,"child_comp" : 9351,"profit" : { "$gte" : { "$numberLong" : "500000000" } } },{ "profit" : { "$lte" : { "$numberLong" : "1000000000" } } }] }).sort({"profit" : 1}).limit(3).explain();
{
"queryPlanner" : {
"plannerVersion" : 1,"namespace" : "test.data","indexFilterSet" : false,"parsedQuery" : {
"$and" : [
{
"child_comp" : {
"$eq" : 9351
}
},{
"parent_comp" : {
"$eq" : 951
}
},{
"profit" : {
"$lte" : {
"$numberLong" : "1000000000"
}
}
},{
"profit" : {
"$gte" : {
"$numberLong" : "500000000"
}
}
}
]
},"queryHash" : "B570EF0C","planCacheKey" : "187EF74B","winningPlan" : {
"stage" : "LIMIT","limitAmount" : 3,"inputStage" : {
"stage" : "FETCH","filter" : {
"$and" : [
{
"child_comp" : {
"$eq" : 9351
}
},{
"parent_comp" : {
"$eq" : 951
}
}
]
},"inputStage" : {
"stage" : "IXSCAN","keyPattern" : {
"profit" : 1
},"indexName" : "profit_index","ismultikey" : false,"multikeyPaths" : {
"profit" : [ ]
},"isUnique" : false,"issparse" : false,"isPartial" : false,"indexVersion" : 2,"direction" : "forward","indexBounds" : {
"profit" : [
"[{ $numberLong: \"500000000\" },{ $numberLong: \"1000000000\" }]"
]
}
}
}
},"rejectedplans" : [
{
"stage" : "SORT","sortPattern" : {
"profit" : 1
},"inputStage" : {
"stage" : "SORT_KEY_GENERATOR","inputStage" : {
"stage" : "FETCH","filter" : {
"$and" : [
{
"parent_comp" : {
"$eq" : 951
}
},{
"profit" : {
"$lte" : {
"$numberLong" : "1000000000"
}
}
},{
"profit" : {
"$gte" : {
"$numberLong" : "500000000"
}
}
}
]
},"inputStage" : {
"stage" : "IXSCAN","keyPattern" : {
"child_comp" : 1
},"indexName" : "child_comp_index","multikeyPaths" : {
"child_comp" : [ ]
},"indexBounds" : {
"child_comp" : [
"[9351.0,9351.0]"
]
}
}
}
}
},{
"stage" : "LIMIT","inputStage" : {
"stage" : "FETCH","inputStage" : {
"stage" : "IXSCAN","keyPattern" : {
"parent_comp" : 1,"child_comp" : 1,"profit" : 1
},"indexName" : "parent_comp_1_child_comp_1_profit_1","multikeyPaths" : {
"parent_comp" : [ ],"child_comp" : [ ],"profit" : [ ]
},"indexBounds" : {
"parent_comp" : [
"[951.0,951.0]"
],"child_comp" : [
"[9351.0,9351.0]"
],"profit" : [
"[{ $numberLong: \"500000000\" },{ $numberLong: \"1000000000\" }]"
]
}
}
}
}
]
},"serverInfo" : {
"host" : "localhost","port" : 27017,"version" : "4.2.8","gitVersion" : "43d25888249164d76d5e04dd6cf38f6111e21f5f"
},"ok" : 1
}
如您所见,获胜计划使用单一索引而不是复合索引。所以,请您让我知道为什么不使用复合索引。
解决方法
您的查询是按利润排序的,并且复合索引不包括您要进行排序的字段,因此使用复合索引将需要一个附加的排序阶段。
权衡和推理将在in the docs中进一步说明。