为什么MongoDB不使用索引交集?

时间:2014-07-16 17:16:37

标签: mongodb indexing

我创建了一个包含单个集合的数据库,该集合存储的文档只包含2个字段(和一个id):

public class Hamster
{
    public ObjectId Id;
    public string Name;
    public int Age;
}

我还为每个字段创建了一个索引。

当我对两个字段执行查询过滤时,我希望它使用Index Intersection组合两个索引,以减少集合扫描并提高性能。这永远不会这种情况。我还没有成功引发指数交叉。

那么,是什么阻止MongoDB应用索引交集呢?

1 个答案:

答案 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对交叉点有很多限制,因此不太可能实际使用。