我为三个属性创建了索引 - a:1,b:1,c:-1
搜索时:
{a: false, b: null, c: {"$lt" : ISODate("2016-06-19T12:19:37.177Z")}}
Mongo使用创建的索引,但仍然需要获取" b"。因此索引仅用于。
但是当我搜索:
{a: false, b: "some value", c: {"$lt" : ISODate("2016-06-19T12:19:37.177Z")}}
我确实使用整个索引。
所以问题是为什么当value为null时,Mongo不使用整个索引?
稀疏选项不会改变任何内容。
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "db.collection",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"a" : {
"$eq" : false
}
},
{
"b" : {
"$eq" : null
}
},
{
"c" : {
"$lt" : ISODate("2016-06-19T12:19:37.177Z")
}
}
]
},
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "KEEP_MUTATIONS",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"b" : {
"$eq" : null
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"a" : NumberLong(1),
"b" : NumberLong(1),
"c" : NumberLong(-1)
},
"indexName" : "a_1_b_1_c_-1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"a" : [
"[false, false]"
],
"b" : [
"[MinKey, MaxKey]"
],
"c" : [
"(new Date(1466338777177), true)"
]
}
}
}
}
},
"rejectedPlans" : []
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 3,
"totalKeysExamined" : 578,
"totalDocsExamined" : 578,
"executionStages" : {
"stage" : "COUNT",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 579,
"advanced" : 0,
"needTime" : 578,
"needFetch" : 0,
"saveState" : 4,
"restoreState" : 4,
"isEOF" : 1,
"invalidates" : 0,
"nCounted" : 577,
"nSkipped" : 0,
"inputStage" : {
"stage" : "KEEP_MUTATIONS",
"nReturned" : 577,
"executionTimeMillisEstimate" : 0,
"works" : 579,
"advanced" : 577,
"needTime" : 1,
"needFetch" : 0,
"saveState" : 4,
"restoreState" : 4,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"b" : {
"$eq" : null
}
},
"nReturned" : 577,
"executionTimeMillisEstimate" : 0,
"works" : 579,
"advanced" : 577,
"needTime" : 1,
"needFetch" : 0,
"saveState" : 4,
"restoreState" : 4,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 578,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 578,
"executionTimeMillisEstimate" : 0,
"works" : 579,
"advanced" : 578,
"needTime" : 0,
"needFetch" : 0,
"saveState" : 4,
"restoreState" : 4,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"a" : NumberLong(1),
"b" : NumberLong(1),
"c" : NumberLong(-1)
},
"indexName" : "a_1_b_1_c_-1",
"isMultiKey" : false,
"direction" : "forward",
"indexBounds" : {
"c" : [
"[false, false]"
],
"b" : [
"[MinKey, MaxKey]"
],
"c" : [
"(new Date(1466338777177), true)"
]
},
"keysExamined" : 578,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
}
}
},
"serverInfo" : {
"host" : "vagrant-ubuntu-trusty-64",
"port" : 27017,
"version" : "3.0.10",
"gitVersion" : "1e0512f8453d103987f5fbfb87b71e9a131c2a60"
},
"ok" : 1.0
}
答案 0 :(得分:0)
经过一些研究,我了解到索引和搜索null的工作方式与其他值完全相同。
无论如何,在做解释时你会发现,对于“null”,你有一个额外的阶段称为“FETCH”,这可能会令人困惑。尽管检查的文档/密钥数量完全相同(测试数据库包含对称数据)。