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

i3a*_*non 12 indexing mongodb

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

public class Hamster
{
    public ObjectId Id;
    public string Name;
    public int Age;
}
Run Code Online (Sandbox Code Playgroud)

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

当我在两个字段上执行查询过滤时,我希望它使用Index Intersection组合两个索引,以减少集合扫描并提高性能.这是从来没有的情况.我还没有设法诱导索引交集.

那么,MongoDB应用索引交集会停止什么呢?

i3a*_*non 13

使用时,explain(true)您可以看到优化程序考虑使用索引交集并选择不:

"cursor" : "BtreeCursor Age", // Chosen plan.
...
"allPlans" : [
   {
       "cursor" : "BtreeCursor Age",
       ...
   },
   {
       "cursor" : "BtreeCursor Name",
       ...
   },
   {
       "cursor" : "Complex Plan", // Index intersection.
       ...
   }
]
Run Code Online (Sandbox Code Playgroud)

MongoDB如果有足够的复合指数,我们永远不会选择交叉点.可以在Index IntersectionJira票证上找到其他限制:

当满足以下条件时,查询优化器可以选择索引交叉计划:
1.相关集合中的大多数文档都是磁盘驻留的.索引交集的优点是当交叉点的大小很小时,它可以避免获取完整的文档.如果文档已经在内存中,则无法通过避免获取来获取任何内容.
2.查询谓词是单点间隔,而不是范围谓词或一组间隔.单点间隔的查询返回按磁盘位置排序的文档,这允许优化器选择以非阻塞方式计算交集的计划.这通常比计算交集的替代模式更快,即使用来自一个索引的结果构建哈希表,然后使用来自第二索引的结果来探测它.
3.要交叉的指数都不具有高度选择性.如果其中一个索引是选择性的,那么优化器将选择一个简单扫描该选择性索引的计划.
4.相对于单索引解决方案扫描的索引键的数量,交集的大小较小.在这种情况下,查询执行程序可以使用索引交集来查看较小的文档集,这可能使我们从磁盘中获得更少的提取.

MongoDB 在交叉点上有许多限制,这使得它不太可能被实际使用.