为什么mongodb无法有效地对复合索引的非前缀子索引进行排序?

时间:2019-08-13 00:45:43

标签: mongodb mongodb-indexes

为什么mongodb无法有效地对复合索引的非前缀子索引进行排序?

https://docs.mongodb.com/manual/tutorial/sort-results-with-indexes/#sort-and-non-prefix-subset-of-an-index

例如,如果您在集合上为{ a: 1, b: 1, c: 1 }编制索引,则可以使用{ a: 1, b: 1 }{ a: 1 }进行排序,这些被称为前缀

find().sort({ a: 1 }).limit(10)

如果我们将相等条件放在“ a”键上,同样的方法,我们可以对“ b”键进行排序而没有问题

find({ a:'example' }).sort({ b: 1 }).limit(10)

通常,如果我们设置属于一个有限集的条件(属于元素列表),我们将能够检索属于该列表的每个键,然后对选定的键执行SORT_MERGE文件限制,因为每个键“ a”使我们可以访问“ b”键的有序索引 因此这些查询通常会使用索引完成

find({ a: { $in: ['exa','ample','test'] }).sort({ b: 1 }).limit(10)

但另一方面,如果我尝试这样的请求:

find().sort({ b: 1 }).limit(10)

他将进行一次COLSCAN(将遍历所有文档),然后对所有数据进行排序,最后取最后10个。 索引{ a: 1, b: 1, c: 1, c: 1 }的使用效率更高。 我们可以扫描索引为“ a”的键,然后对请求的限制执行SORT_MERGE。 最后,它使我们成为O(键+限制)算法,其中键是不同的“ a”键的数量,并限制了我们要检索的文档数量。它为我们节省了COLSCAN,并且使我们免于对收集的数据进行排序。 合理地假设与文档相比,不同的“ a”键要少一些,因为不应使用复合索引。不同的“ a”键越少,应该感觉到的性能提升就更多。

在这里我只提到了在第一个索引上没有任何条件的情况,但是如果我们添加这样的条件

find({ { a: { $gt: 100 } }).sort({ b: 1 }).limit(10)
find({ a: /^spa/i }).sort({ b: 1 }).limit(10)

我们可以想象完全相同的操作,只是我们限制了要扫描的“ a”键的数量。

对于某些请求,我们甚至可以在某些情况下获得疯狂的性能,甚至在没有一些子索引的情况下也可以做到

我在哪里错了?

0 个答案:

没有答案