假设我有一个User集合,其中的文档看起来像这样
{ "名称":" Starlord", "年龄":24, "性别":"男", "身高":180, "体重":230, "爱好":"飞行太空飞船" }
现在,我希望有人能够根据这些字段中的一个或多个来搜索用户。所以我按照上面的顺序添加一个包含所有这些字段的复合索引。
问题是当查询字段是索引字段的前缀时,MongoDB索引很有用。例如,如果我按name
,age
和gender
进行查询,那么查询的效果就会很好。如果我按name
,gender
和weight
进行查询,那么查询的效果就不那么好了(虽然它仍然使用索引并且比无索引更快)。
当您有这样的用例时,您使用什么索引策略?
答案 0 :(得分:1)
name
,age
和gender
的查询在name
,gender
和weight
进行查询时效果很好的原因不是因为字段的顺序对MongoDB中的复合索引有很大影响,特别是索引的前缀。如文档中this page中所述,复合索引可以支持对其字段的任何前缀的查询。因此,假设您按照提交字段的顺序创建了索引,name
,age
和gender
的查询是复合索引的前缀,而name
,{ {1}}和gender
只能利用索引的weight
部分。
在这些字段上支持所有可能的查询组合需要您创建足够的复合索引,以便所有可能的查询都是索引的前缀。我会说这不是你想做的事情。由于您的问题询问有多个字段的查询的索引策略,我建议您查看对您的数据集最有用的特定数据访问模式,并创建一些支持这些的复合索引,利用前缀概念和省略索引中基数较低的某些字段,例如name
。
答案 1 :(得分:0)
如果您需要能够查询所有组合,则索引数量需要快速爆炸。拯救的功能称为"index intersection"。
在每个字段上创建一个简单的索引,并信任查询优化器以执行正确的索引交集。此功能相对较新(从2.6开始),而不是像众所周知的RBDMSses那样完整。跟踪Jira Ticket for index intersections以了解限制是有意义的,因为限制非常严重。仔细混合简单的索引(可以交叉)和复合索引(对于非常常见的查询)通常是有意义的。
在您的特定情况下,您可以利用以下事实:许多字段是数字的,并且有效值的范围非常有限(例如,年龄,身高和体重)。 gender
字段的选择性较低,在任何情况下都不应编入索引。在最后一步中过滤性别,因为它平均只会使必须处理的数据量增加一倍。
创建n!
复合索引几乎肯定不是n > 3
...