mongo 查询不触发复合索引
mongo query does not trigger compound index
我有成百上千个这样的文档:
{
"field_id" : "abcd",
"aField" : 0,
"parentList": [
{
"field": "value1",
"list": ["element1,element2"]
}
,
{
"field": "value2",
"list": ["element1, element3"]
}
]
}
(这是我数据库中一个更大文档的过度简化版本,包含更多字段。数据库包含数百万个文档)。
这是我想用于计数执行的过滤器:
{ 'parentList.0.list':
{ '$in':
[ 'element1',
'element2',
'element3',
'element4'
]
},
aField: { '$ne': 1 },
field_id: { '$in': [ 'abcd' ] }
}
我想做的是创建一个这样的索引:
{"field_id" : 1, "parentList.list" :1, "aField" : 1}
并让查询使用它。但是 mongo 实际上是忽略了它。相反,mongo 使用另一个索引,即
{"field_id":1, "anotherField":1}
执行统计显示此阶段:
- IXSCAN on {"field_id":1, "anotherField":1} 索引,产生 500k keysExamined,这是具有 field_id = 'abcd'[= 的 500k 文档32=]
- 获取过滤器的其余部分,返回 20k 作为计数
当然,如果 mongo 使用了正确的索引,我希望它已经从 IXSCAN 中检索到 20k 的文档,或者至少接近这个数字。
我只是不明白为什么 mongo 没有使用那个索引。我还尝试更改索引中字段的顺序,但没有成功。
我正在使用 Mongo 4.4.6
Mongo 有时会使用错误的索引,我建议您阅读我的回答 ,其中解释了为什么会发生这种情况。
为了“修复”您应该使用 $hint 的行为,它将强制 Mongo 使用您指定的特定索引。
是否索引
{"field_id":1, "anotherField":1}
适用于针对您的数据库的大多数查询吗?
根据我的经验,MongoDB 通常会选择非常通用的索引,即使有时更具体的索引更好。我通过使索引更具体地用于它们的用途(并删除“包罗万象”的索引)来解决这个问题。我不知道这是否适用于您的用例,因为不知道选择索引的原因。
已解决
所以这其实很容易解决。 MongoDB Compass 不允许我在数组的某个位置创建索引(在本例中为 parentList.0.list),因为当我尝试插入它时,它会自动将其替换为 parentList.list.
最终,我发现如果在 shell 中完成,数组的某个位置上的索引实际上是可行的。所以我在 parentList.0.list 上创建了索引并且索引工作正常。
而已。希望这对其他人也有帮助。
我有成百上千个这样的文档:
{
"field_id" : "abcd",
"aField" : 0,
"parentList": [
{
"field": "value1",
"list": ["element1,element2"]
}
,
{
"field": "value2",
"list": ["element1, element3"]
}
]
}
(这是我数据库中一个更大文档的过度简化版本,包含更多字段。数据库包含数百万个文档)。 这是我想用于计数执行的过滤器:
{ 'parentList.0.list':
{ '$in':
[ 'element1',
'element2',
'element3',
'element4'
]
},
aField: { '$ne': 1 },
field_id: { '$in': [ 'abcd' ] }
}
我想做的是创建一个这样的索引:
{"field_id" : 1, "parentList.list" :1, "aField" : 1}
并让查询使用它。但是 mongo 实际上是忽略了它。相反,mongo 使用另一个索引,即
{"field_id":1, "anotherField":1}
执行统计显示此阶段:
- IXSCAN on {"field_id":1, "anotherField":1} 索引,产生 500k keysExamined,这是具有 field_id = 'abcd'[= 的 500k 文档32=]
- 获取过滤器的其余部分,返回 20k 作为计数
当然,如果 mongo 使用了正确的索引,我希望它已经从 IXSCAN 中检索到 20k 的文档,或者至少接近这个数字。
我只是不明白为什么 mongo 没有使用那个索引。我还尝试更改索引中字段的顺序,但没有成功。 我正在使用 Mongo 4.4.6
Mongo 有时会使用错误的索引,我建议您阅读我的回答
为了“修复”您应该使用 $hint 的行为,它将强制 Mongo 使用您指定的特定索引。
是否索引
{"field_id":1, "anotherField":1}
适用于针对您的数据库的大多数查询吗?
根据我的经验,MongoDB 通常会选择非常通用的索引,即使有时更具体的索引更好。我通过使索引更具体地用于它们的用途(并删除“包罗万象”的索引)来解决这个问题。我不知道这是否适用于您的用例,因为不知道选择索引的原因。
已解决
所以这其实很容易解决。 MongoDB Compass 不允许我在数组的某个位置创建索引(在本例中为 parentList.0.list),因为当我尝试插入它时,它会自动将其替换为 parentList.list. 最终,我发现如果在 shell 中完成,数组的某个位置上的索引实际上是可行的。所以我在 parentList.0.list 上创建了索引并且索引工作正常。 而已。希望这对其他人也有帮助。