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_1
或b_1_a_1
查询:{a: x, b: { $in: [....] } }
哪个索引更好?还是一样?
查询匹配数组如何工作?
更新:
分片键会影响查询索引吗?
分片键:a_1_c_1
额外索引:b_1_a_1
查询:{a: x, b: y}
a=x
中的a_1_c_1
路由到分片,然后使用索引b_1_a_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
。>
但是,这过于简单了。实际的性能影响可以忽略不计,尤其是在a
和b
的可能范围很小的情况下。
还应考虑一个额外的注意事项:查询前缀。如果发现自己有时只使用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_1
和b_1
,为您提供介于性能和灵活性之间的中间点。
考虑到以上所有内容,我不建议您过多地关注索引性能,除非您需要数据大小。毕竟,您可以删除旧索引并根据需要构建新索引。使用目前有效的方法,随着时间的推移监视性能,并在您看起来可能超出当前使用的方法时重新评估。