Mongodb 优化Mongo查询

Mongodb 优化Mongo查询,mongodb,Mongodb,我是Mongo的新手,我一直在尝试获得不同的用户数量。字段Id和状态不是单独索引的列,但在这两个字段上都存在复合索引。我当前的查询是这样的,其中匹配条件根据需求而变化 DBQuery.shellBatchSize = 1000000; db.getCollection('username').aggregate([ {$match: { Status: "A" } }, {"$group" : {_id:"$Id", count:{$sum:1}}} ]); 我们是否可

我是Mongo的新手,我一直在尝试获得不同的用户数量。字段Id和状态不是单独索引的列,但在这两个字段上都存在复合索引。我当前的查询是这样的,其中匹配条件根据需求而变化

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。