MongoDB 复合索引实际上是如何工作的?
How does MongoDB compound indexes actually work?
我在 mongodb 中创建复合索引时,我发现了一个奇怪的行为。
我创建了一个索引:
db.getCollection('Subject').createIndex({a:1, b:2, c:3})
它创建了一个名为 a_1_b_2_c_3
的索引。
现在,当我使用 mongo 查找命令时:
db.getCollection('Subject').find({a:1, b:2, c:3}) //it works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({a:1, b:2}) //this also works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({a:1, c:2}) //this also works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({b:1, c:2}) //But this command doesn't uses the index `a_1_b_2_c_3`.
谁能告诉我为什么会发生这种行为?
这是由于 index prefixes。索引 {a:1, b:1, c:1}
具有前缀 { a: 1 }
和 { a: 1, b: 1}
,因此在这些字段上包含过滤器的查询将使用该索引。
从概念上讲,可以将索引想象成一个 B 树,它以 a
上的过滤器开始,并且在 b
和 c
的较低级别上有子树。较早的查询可以很容易地从树的顶部开始向下进行,而最后一个查询 ({b:1, c:2}
) 不会有一个简单的起点。
如果你还想强制MongoDB使用你的索引,你可以伪造查询如下(我已经测试过了)。在这种情况下,我假设 collection 中 'a' 的值仅为正整数。
db.Subject.explain("executionStats").find({a:{$gt:-1}, b:1, c:2})
这可能会影响其他应用程序功能,或者如果此类查询是标准模式,则创建专用索引来处理查询。
我在 mongodb 中创建复合索引时,我发现了一个奇怪的行为。 我创建了一个索引:
db.getCollection('Subject').createIndex({a:1, b:2, c:3})
它创建了一个名为 a_1_b_2_c_3
的索引。
现在,当我使用 mongo 查找命令时:
db.getCollection('Subject').find({a:1, b:2, c:3}) //it works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({a:1, b:2}) //this also works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({a:1, c:2}) //this also works fine `a_1_b_2_c_3` is used.
db.getCollection('Subject').find({b:1, c:2}) //But this command doesn't uses the index `a_1_b_2_c_3`.
谁能告诉我为什么会发生这种行为?
这是由于 index prefixes。索引 {a:1, b:1, c:1}
具有前缀 { a: 1 }
和 { a: 1, b: 1}
,因此在这些字段上包含过滤器的查询将使用该索引。
从概念上讲,可以将索引想象成一个 B 树,它以 a
上的过滤器开始,并且在 b
和 c
的较低级别上有子树。较早的查询可以很容易地从树的顶部开始向下进行,而最后一个查询 ({b:1, c:2}
) 不会有一个简单的起点。
如果你还想强制MongoDB使用你的索引,你可以伪造查询如下(我已经测试过了)。在这种情况下,我假设 collection 中 'a' 的值仅为正整数。
db.Subject.explain("executionStats").find({a:{$gt:-1}, b:1, c:2})
这可能会影响其他应用程序功能,或者如果此类查询是标准模式,则创建专用索引来处理查询。