我创建了一个包含单个集合的数据库,该集合存储的文档只包含2个字段(和一个id):
public class Hamster
{
public ObjectId Id;
public string Name;
public int Age;
}
我还为每个字段创建了一个索引。
当我对两个字段执行查询过滤时,我希望它使用Index Intersection组合两个索引,以减少集合扫描并提高性能。这永远不会这种情况。我还没有成功引发指数交叉。
那么,是什么阻止MongoDB
应用索引交集呢?
答案 0 :(得分:12)
当您使用explain(true)
时,您可以看到优化程序考虑使用索引交集并选择不:
"cursor" : "BtreeCursor Age", // Chosen plan.
...
"allPlans" : [
{
"cursor" : "BtreeCursor Age",
...
},
{
"cursor" : "BtreeCursor Name",
...
},
{
"cursor" : "Complex Plan", // Index intersection.
...
}
]
如果有足够的复合索引, MongoDB
将永远不会选择交集。其他限制可以在Jira ticket for Index Intersection上找到:
当满足以下条件时,查询优化器可以选择索引交叉点计划:
1.相关集合中的大多数文档都是磁盘驻留的。索引交集的优点是当交叉点的大小很小时,它可以避免获取完整的文档。如果文件已经在记忆中,那么避免取物就没有任何好处 2.查询谓词是单点间隔,而不是范围谓词或一组间隔。单点间隔的查询返回按磁盘位置排序的文档,这允许优化器选择以非阻塞方式计算交集的计划。这通常比计算交集的替代模式更快,即使用一个索引的结果构建哈希表,然后使用第二个索引的结果进行探测。 3.要交叉的指数都不具有高度选择性。如果其中一个指数是选择性的,那么优化器将选择一个简单扫描该选择性指数的计划 4.相对于单索引解决方案扫描的索引键的数量,交集的大小较小。在这种情况下,查询执行程序可以使用索引交集来查看较小的文档集,这可能使我们从磁盘中获得更少的提取。
MongoDB
对交叉点有很多限制,因此不太可能实际使用。