我在理解复合索引的基本概念时遇到了麻烦。 假设我有一个这个模式的集合:
{
_id: 1,
field1: 'aaa',
field2: 'bbb',
field3: 'ccc'
}
在https://docs.mongodb.org/manual/core/index-compound/中,它非常清楚地表明,我明白,这个索引:{ field1: 1, field: 2}
仅支持field1
和field1 AND field2
上的查询,这是有道理的。
现在,如果我想支持始终使用字段1的所有字段(1,2和3)的查询,该怎么办?
我想支持在所有field1 AND field2
上查询field1 AND field3
和field1 AND field2 AND field3
的选项。
我知道可以为每个查询选项创建复合索引,但问题是我是否可以使用更少的化合物来查询相同的性能。
例如,如果我有一个索引:{field1: 1, field2: 1, field3: 1}
并且我查询field1 AND field3
,它将使用此索引,但field2
上的索引边界将是"[MinKey, MaxKey]"
}。
是否值得创建另一个索引:{field1: 1, field3: 1}
?
答案 0 :(得分:0)
如果您尝试使用这些文档和索引创建集合,然后对查询进行说明,mongo将选择索引:{field1: 1, field3: 1}
并拒绝其他计划。这表明mongo找到一个比另一个索引更好的索引。
例如,解释返回以下内容:
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"field1" : 1,
"field3" : 1
},
"indexName" : "field1_1_field3_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"field1" : [
"[\"aaa\", \"aaa\"]"
],
"field3" : [
"[\"ccc\", \"ccc\"]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"field3" : {
"$eq" : "ccc"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"field1" : 1,
"field2" : 1
},
"indexName" : "field1_1_field2_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"field1" : [
"[\"aaa\", \"aaa\"]"
],
"field2" : [
"[MinKey, MaxKey]"
]
}
}
},
{
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"field1" : 1,
"field2" : 1,
"field3" : 1
},
"indexName" : "field1_1_field2_1_field3_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"field1" : [
"[\"aaa\", \"aaa\"]"
],
"field2" : [
"[MinKey, MaxKey]"
],
"field3" : [
"[\"ccc\", \"ccc\"]"
]
}
}
}
]
然而,存在索引大小的问题,以及您要创建的所有索引是否都适合数据库工作集中的RAM。如果它们没有那么它将把索引保存在磁盘上,这显然要慢一些。那么最好的折衷方案可能是在所有三个字段上使用索引,因为这比没有索引好,并且涉及的维护少于三个索引