我正在使用mongodb 2.6
,我有以下查询:
db.getCollection('Jobs').find(
{ $and: [ { RunID: { $regex: ".*_0" } },
{ $or: [ { JobType: "TypeX" },
{ JobType: "TypeY" },
{ JobType: "TypeZ" },
{ $and: [ { Info: { $regex: "Weekly.*" } }, { JobType: "YetAnotherType" } ] } ] } ] })
我有三个不同的索引:RunID
,RunID + JobType
,RunID + JobType + Info
。 Mongo总是只使用包含RunID的索引,虽然其他索引似乎更有可能产生更快的结果,有时甚至使用由RunID + StartTime
组成的索引,而StartTime甚至不在使用字段列表中,任何想法为什么选择该指数?
答案 0 :(得分:2)
注1:
您可以删除前两个索引,RunID
和RunID + JobType
。只使用扩展复合索引RunID + JobType + Info
就足够了;这也可用于查询RunID
或RunID + JobType
字段,info here:
除了支持所有索引字段匹配的查询外, 复合索引可以支持与前缀匹配的查询 索引字段。
当您删除这些索引时,mongo将选择唯一的剩余索引。
注2:
您可以随时使用hint告诉mongo使用特定索引:
db.getCollection('Jobs').find().hint({RunID:1, JobType:1, Info:1})
答案 1 :(得分:1)
感谢Sergiu's answer和Sammaye's comment,我想我找到了我要找的东西:
我删除了RunID
索引,因为RunID
是许多其他索引中的前缀,mongodb
只有RunID
才会使用它。< / p>
关于$or
,我们在documentation中有以下内容:
在评估$或表达式中的子句时,MongoDB也是如此 执行集合扫描,或者,如果支持所有子句,则执行 索引,MongoDB执行索引扫描。也就是说,对于MongoDB来说 用于计算$或表达式的索引,$或中的所有子句 表达式必须由索引支持。否则,MongoDB会 执行收集扫描。
正如我之前提到的,RunID
已被编入索引,因此我们需要查询中其他字段的新索引:JobType
和Info
,因为JobType
需要作为索引的前缀,以便它可以在不包含Info
字段的查询中使用,所以我创建的第二个索引是
{ "JobType": 1.0, "Info": 1.0}
因此,mongodb将使用一个复杂的计划,其中将使用不同的索引。