使用in和两个索引之间的数组进行查询有什么区别?

时间:2019-05-15 04:26:01

标签: sql database mongodb

MongoDB中具有如下文档的集合:

{a: 1, b: 1}
{a: 2, B: 2}
{a: 3, B: 3}
{a: 3, B: 2}
{a: 2, B: 1}

具有uniq索引a_1_b_1b_1_a_1

查询:{a: x, b: { $in: [....] } }

哪个索引更好?还是一样?

查询匹配数组如何工作?


更新: 分片键会影响查询索引吗? 分片键:a_1_c_1 额外索引:b_1_a_1 查询:{a: x, b: y}

  1. 由分片键a=x中的a_1_c_1路由到分片,然后使用索引b_1_a_1在分片中进行查询
  2. 通过分片键进行路由和查询是否必须使用分片键?

1 个答案:

答案 0 :(得分:0)

来自compound indexes的MongoDB手册部分:

  
    

db.products.createIndex({“ item”:1,“ stock”:1})

  
     

复合索引中列出的字段的顺序很重要。索引将包含对文档的引用,这些文档首先按项目字段的值排序,然后在项目字段的每个值内,按库存字段的值排序。

鉴于上述情况,我们可以看到a_1_b_1首先按a进行分段,然后按b进行分段,而b_1_a_1首先按b进行分段,然后然后a

现在让我们检查一下您的查询:{a: x, b: { $in: [....] } }
请注意,此查询匹配特定的a值和可能的b值的范围。在索引a_1_b_1中,索引扫描将仅限于匹配的a块,并且将在所有b值中搜索;但是,如果使用索引b_1_a_1,则索引扫描必须在不同的b块之间“跳转”,并在每个块中搜索匹配的a值。

访问“紧密”在一起的数据通常效率更高,因此您将需要选择索引,在该索引中更可能将匹配文档放置在紧密位置。在这种情况下,将所有文档放在相同的a块中将是一个更好的选择,因为应该减少“跳跃”的发生,因此应该使用索引a_1_b_1

但是,这过于简单了。实际的性能影响可以忽略不计,尤其是在ab的可能范围很小的情况下。

还应考虑一个额外的注意事项:查询前缀。如果发现自己有时只使用a值执行查询,则应选择索引a_1_b_1。同样,如果有时您仅使用b值执行查询,则应该选择b_1_a_1

这是因为,如果您的查询与索引不完全匹配,但与该索引的前缀匹配,则该索引仍然适用。因此,在索引a_1_b_1中,您可以对{a: x, b: {$in: [....]}}{a: x}进行有效查询,但是不能对{b: {$in: [....]}}进行有效查询。

最后,通常还可以利用index intersection来拥有两个单独的索引a_1b_1,为您提供介于性能和灵活性之间的中间点。


考虑到以上所有内容,我不建议您过多地关注索引性能,除非您需要数据大小。毕竟,您可以删除旧索引并根据需要构建新索引。使用目前有效的方法,随着时间的推移监视性能,并在您看起来可能超出当前使用的方法时重新评估。