Mongodb 优化Mongo查询
我是Mongo的新手,我一直在尝试获得不同的用户数量。字段Id和状态不是单独索引的列,但在这两个字段上都存在复合索引。我当前的查询是这样的,其中匹配条件根据需求而变化Mongodb 优化Mongo查询,mongodb,Mongodb,我是Mongo的新手,我一直在尝试获得不同的用户数量。字段Id和状态不是单独索引的列,但在这两个字段上都存在复合索引。我当前的查询是这样的,其中匹配条件根据需求而变化 DBQuery.shellBatchSize = 1000000; db.getCollection('username').aggregate([ {$match: { Status: "A" } }, {"$group" : {_id:"$Id", count:{$sum:1}}} ]); 我们是否可
DBQuery.shellBatchSize = 1000000;
db.getCollection('username').aggregate([
{$match:
{ Status: "A"
} },
{"$group" : {_id:"$Id", count:{$sum:1}}}
]);
我们是否可以进一步优化此查询或在集合上添加并行运行,以便更快地获得结果
关于您可以通过在聚合方法中传入
explain=true
选项来调整聚合管道
db.getCollection('username').aggregate([
{$match: { Status: "A" } },
{"$group" : {_id:"$Id", count:{$sum:1}}}],
{ explain: true });
然后将输出以下内容以进行处理
{
"stages" : [
{
"$cursor" : {
"query" : {
"Status" : "A"
},
"fields" : {
"Id" : 1,
"_id" : 0
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.usernames",
"indexFilterSet" : false,
"parsedQuery" : {
"Status" : {
"$eq" : "A"
}
},
"winningPlan" : {
"stage" : "EOF"
},
"rejectedPlans" : [ ]
}
}
},
{
"$group" : {
"_id" : "$Id",
"count" : {
"$sum" : {
"$const" : 1
}
}
}
}
],
"ok" : 1
}
因此,为了加快查询速度,我们需要一个索引来帮助匹配管道的一部分,因此,让我们在Status
> db.usernames.createIndex({Status:1})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
如果我们现在再次运行explain,我们将得到以下结果
{
"stages" : [
{
"$cursor" : {
"query" : {
"Status" : "A"
},
"fields" : {
"Id" : 1,
"_id" : 0
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.usernames",
"indexFilterSet" : false,
"parsedQuery" : {
"Status" : {
"$eq" : "A"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"Status" : 1
},
"indexName" : "Status_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Status" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Status" : [
"[\"A\", \"A\"]"
]
}
}
},
"rejectedPlans" : [ ]
}
}
},
{
"$group" : {
"_id" : "$Id",
"count" : {
"$sum" : {
"$const" : 1
}
}
}
}
],
"ok" : 1
}
我们现在可以直接看到这是使用索引
您可以通过在聚合方法中传入
explain=true
选项来调整聚合管道
db.getCollection('username').aggregate([
{$match: { Status: "A" } },
{"$group" : {_id:"$Id", count:{$sum:1}}}],
{ explain: true });
然后将输出以下内容以进行处理
{
"stages" : [
{
"$cursor" : {
"query" : {
"Status" : "A"
},
"fields" : {
"Id" : 1,
"_id" : 0
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.usernames",
"indexFilterSet" : false,
"parsedQuery" : {
"Status" : {
"$eq" : "A"
}
},
"winningPlan" : {
"stage" : "EOF"
},
"rejectedPlans" : [ ]
}
}
},
{
"$group" : {
"_id" : "$Id",
"count" : {
"$sum" : {
"$const" : 1
}
}
}
}
],
"ok" : 1
}
因此,为了加快查询速度,我们需要一个索引来帮助匹配管道的一部分,因此,让我们在Status
> db.usernames.createIndex({Status:1})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
如果我们现在再次运行explain,我们将得到以下结果
{
"stages" : [
{
"$cursor" : {
"query" : {
"Status" : "A"
},
"fields" : {
"Id" : 1,
"_id" : 0
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.usernames",
"indexFilterSet" : false,
"parsedQuery" : {
"Status" : {
"$eq" : "A"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"Status" : 1
},
"indexName" : "Status_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Status" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Status" : [
"[\"A\", \"A\"]"
]
}
}
},
"rejectedPlans" : [ ]
}
}
},
{
"$group" : {
"_id" : "$Id",
"count" : {
"$sum" : {
"$const" : 1
}
}
}
}
],
"ok" : 1
}
我们现在可以直接看到这是使用索引
如果需要,您可以使用
distinct
query。这里的链接Direct distinct将在非索引字段上花费更长的时间,根据mongo doc,最佳调优方法是创建索引。。如果需要,可以使用distinct
查询。这里的链接Direct distinct将在非索引字段上花费更长的时间,根据mongo doc,最佳调优方法是创建索引。。谢谢你,凯文。问题是我不能去创建索引,因为我是DB的唯一消费者。因此,我想检查是否有不创建新索引的方法,或者是否有利用现有复合索引的方法。运行解释,看看它说了什么,如果可以,它应该使用索引集。(您可以跨当前配置的索引发送吗?db.usernames.getIndexes()
)。另外,最好不要只是随机创建索引,您希望拥有满足最多查询量的最低数量的索引。当前存在的索引集是Id\U状态。。其中包含ID字段和状态字段。。另外,explain显示它没有使用index.stages.$cursor.queryPlanner.indexFilterSet:false如果索引是{u-id:1,Status:1}
,则不会使用它,因为您需要同时查询{u-id和Status。谢谢Kevin。问题是我不能去创建索引,因为我是DB的唯一消费者。因此,我想检查是否有不创建新索引的方法,或者是否有利用现有复合索引的方法。运行解释,看看它说了什么,如果可以,它应该使用索引集。(您可以跨当前配置的索引发送吗?db.usernames.getIndexes()
)。另外,最好不要只是随机创建索引,您希望拥有满足最多查询量的最低数量的索引。当前存在的索引集是Id\U状态。。其中包含ID字段和状态字段。。另外,explain显示它没有使用index.stages.$cursor.queryPlanner.indexFilterSet:false如果索引是{u id:1,Status:1}
,则不会使用它,因为您需要同时查询_id和Status。