我有以下查询:
a : true AND (b : 1 OR b : 2) AND ( c: null OR (c > startDate AND c <endDate))
所以基本上我在考虑所有三个字段的复合索引,因为我根本没有排序。在第一步,使用布尔字段上的索引,我将消除文档的最大部分。
然后使用第二个字段的索引,我看到OR子句创建了两个单独的查询,然后将它们组合在一起,同时删除重复项。所以这应该非常快速有效。
最后一个条件是一个简单的日期范围,所以我认为将该字段添加到索引将是一个不错的选择。
对我的想法有什么建议吗?感谢
答案 0 :(得分:1)
此查询:
a : true AND (b : 1 OR b : 2) AND ( c: null OR (c > startDate AND c <endDate))
否则可翻译为:
db.collection.find({
a:true,
b:{$in:[1,2]},
$or: [
{c:null},
{c: {$gt: startDate, $lt: endDate}}
]
})
由于$or
,您很可能需要两个索引,因为$or
仅涵盖c
,因此您只需要c
上的索引。这是我们的第一个索引:
db.collection.ensureIndex({c:1})
现在我们不能将$or
与复合索引一起使用,因为复合索引以前缀方式工作,而$or
被评估为每个子句的完全独立的查询,因此最好使用a,b
作为我们索引的前缀。
这意味着您只需要一个索引来覆盖查询的其他部分:
db.collection.ensureIndex({b:1,a:1})
由于b
的布尔值,我们先将a
放在首位,我们的索引应首先使用b
执行得更好。
注意:由于基数较低,我不确定a
上的索引。