0

我有以下查询:

a : true AND (b : 1 OR b : 2) AND ( c: null OR (c > startDate AND c <endDate))

所以基本上我正在考虑所有三个字段的复合索引,因为我根本没有排序。第一步,使用布尔字段上的索引,我将消除文档的最大部分。

然后使用第二个字段上的索引,我看到 OR 子句创建了两个单独的查询,然后将它们组合起来,同时删除重复项。所以这应该是非常快速和有效的。

最后一个条件是一个简单的日期范围,所以我认为将字段添加到索引将是一个不错的选择。

对我的想法有什么建议吗?谢谢

4

1 回答 1

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})

现在我们不能将 the$or与复合索引一起使用,因为复合索引以前缀方式工作,并且$ors 被评估为每个子句的完全独立的查询,因此最好在a,b这里用作我们索引的前缀。

这意味着您只需要一个索引来覆盖查询的其他部分:

db.collection.ensureIndex({b:1,a:1})

b由于 的布尔值,我们将其放在首位a,我们的索引应该在bfirst 时表现更好。

注意:a由于基数较低,我完全不确定索引是否存在。

于 2013-07-04T07:11:03.403 回答