我正在查询mongo数据库集合,并且返回结果相当缓慢。 使用不同的查询,可以将相同的信息更快地拉出1000倍以上。不幸的是,我并不总是拥有快速查询所需的信息。
问题似乎与Mongo引擎似乎在查询中使用“错误”索引有关。
如果在$in
子句中指定了数据,则具体地说,它不使用预期的索引。
我试图理解为什么mongo引擎选择它要执行的索引而不是“正确的”索引,以及我可以做什么(如果有的话)让Mongo引擎选择(我认为是)“正确的索引。
这是我的集合中定义的索引的(截断的)列表:
db.Documents.getIndexes()
// returns
[
{
"v" : 1,
"key" : {
"isActive" : 1,
"data.type" : 1
},
"name" : "isActive_1_data.type_1",
"ns" : "SoforCms.Documents",
"partialFilterExpression" : {
"isActive" : true
}
},
{
"v" : 1,
"key" : {
"isActive" : 1,
"data.type" : 1,
"data.identities" : 1
},
"name" : "isActive_1_data.type_1_data.identities_1",
"ns" : "SoforCms.Documents",
"partialFilterExpression" : {
"isActive" : true,
"data.type" : "legalDoc"
}
},
... other indexes removed for brevity
]
在以下查询中,使用第一个索引而不是第二个索引(导致性能不佳):
db.Documents.find({
isActive: true,
'data.type':'legalDoc',
'data.identities': {'$in' : [{id: '41', type: 'legacy'},
{id : "23140", type : "legacy" }]}
}).explain()
这将导致使用第一个索引的查询计划:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "SoforCms.Documents",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"data.type" : {
"$eq" : "legalDoc"
}
},
{
"isActive" : {
"$eq" : true
}
},
{
"data.identities" : {
"$in" : [
{
"id" : "23140",
"type" : "legacy"
},
{
"id" : "41",
"type" : "legacy"
}
]
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"data.identities" : {
"$in" : [
{
"id" : "23140",
"type" : "legacy"
},
{
"id" : "41",
"type" : "legacy"
}
]
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"isActive" : 1,
"data.type" : 1
},
"indexName" : "isActive_1_data.type_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"isActive" : [
"[true, true]"
],
"data.type" : [
"[\"legalDoc\", \"legalDoc\"]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"data.identities" : {
"$in" : [
{
"id" : "23140",
"type" : "legacy"
},
{
"id" : "41",
"type" : "legacy"
}
]
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"isActive" : 1,
"data.type" : 1,
"data.identities" : 1
},
"indexName" : "isActive_1_data.type_1_data.identities_1",
"isMultiKey" : true,
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"isActive" : [
"[true, true]"
],
"data.type" : [
"[\"legalDoc\", \"legalDoc\"]"
],
"data.identities" : [
"[MinKey, MaxKey]"
]
}
}
},
// other rejected plans removed for brevity
]
},
"serverInfo" : {
...
},
"ok" : 1.0
}
如果我仅查询一个文档,则使用预期的(第二个)索引,查询运行速度快10_000倍!
db.Documents.find({'isActive': true,
'data.type':'legalDoc',
'data.identities': {id: '41', type: 'legacy'}})
欢迎提供有关替代索引定义或替代查询方式的任何建议。
当前,运行几个查询一次获取一个文档而不是在查询中获取所有文档的效率要高得多,但这感觉很不对。