我在MongoDB中经历过很多关于索引的文章,但对我的特定情况仍然没有明确的索引策略理解。
我拥有超过1000万件物品的以下系列:
{
active: BOOLEAN,
afp: ARRAY_of_integers
}
以前我在这个管道上使用聚合:
pipeline = [
{'$match': {'active': True}},
{'$project': {
'sub': {'$setIsSubset': [afp, '$afp']}
}},
{'$match': {'sub': True}}
]
查询非常慢,所以我开始尝试没有聚合:
db.collection.find({'active': True, 'afp': {'$all': afp}})
使用$ all的后一个查询使用相同的索引运行得更快 - 不知道为什么......
我已经尝试过这些索引(尽管可能没有太多变化):
{afp: 1}
{active: 1}
{active: 1, afp: 1}
{afp: 1, active: 1}
我不知道为什么,但是最新的索引给出了最好的表现 - 任何关于这个原因的想法都会受到高度赞赏。
然后我决定添加约束以便可能提高速度。 考虑到“afp”字段中的整数数量可能不同,没有理由扫描整数数量少于查询的文档。所以我为所有名为“len_afp”的文件创建了一个字段,其中包含该数字(确实是afp长度)。 现在文档看起来像这样:
{
active: BOOLEAN,
afp: ARRAY_of_integers
len_afp: INTEGER
}
查询是:
db.collection.find({
'active': True,
'afp': {'$all': afp},
'len_afp: {'$gte': len_afp}
})
此外,我添加了三个新索引:
{afp: 1, len_afp: 1, active: 1}
{afp: 1, active: 1, len_afp: 1}
{len_afp: 1, afp: 1, active: 1}
最新的指数表现最佳 - 再次出于不明原因。
所以我的问题是:复合索引中字段顺序的逻辑是什么,以及在创建索引时如何考虑这个逻辑?
同样有趣的是,为什么$ all比其他条件相同的$ setIsSubset更快?
可以将索引交集用于我的案例而不是复合索引吗?
性能仍然很低 - 我做错了什么? 在我的特定情况下可以分片帮助(它会使用聚合,还是$ all,或$ gte)?
抱歉提出了大问题,并提前感谢您!