2014-10-18 57 views
1

我们有一个复合索引像{a,b,c}和查询是像

{$or:[{a: <value 1>, b: <value 2>}, {a: <value 2>, b: <value 1>}], c: {$gte: <value c1>, $lte: <value c2>}} 

然后,索引用于仅部分即

indexBounds" : { 
          "a" : [ 
            [ 
              <value 1>, 
              <value 1> 
            ] 
          ], 
          "b" : [ 
            [ 
              <value 2>, 
              <value 2> 
            ] 
          ], 
          "c" : [ 
            [ 
              { 
                "$maxElement" : 1 
              }, 
              { 
                "$minElement" : 1 
              } 
            ] 

和其它类似的光标与其他价值的组合。结果数据将在'c'上过滤。因此,我们有比最终结果更多的nscannned和nscannedobjects。 如果我们有查询,如下

{$or:[{a: <value 1>, b: <value 2>, c: {$gte: <value c1>, $lte: <value c2>}}, {a: <value 2>, b: <value 1>, c: {$gte: <value c1>, $lte: <value c2>}}]} 

则索引完全使用,我们已经nscanned = N 的问题 - 这是$或试图对任何使用索引表达式中,而正常行为比结合整个查询还是缺少任何东西。

回答

0

这是正常行为。查询计划人员使用{ "a" : 1, "b" : 1, "c" : 1 }上的索引来完成查询的$or子句,因为计划人员已经确定这是用索引完成查询的最佳(唯一?)方法。由于连接通过析取来分配,所以(X OR Y) AND Z(您的第一个查询的结构)等于(X AND Z) OR (Y AND Z)(您的第二个查询的结构),但索引可以更好地用于后一个查询。查询规划器不会重新排列查询的逻辑,有时候还有更好的方法来编写查询,以便查询规划器可以最大限度地使用索引。