在这个问题的评论中,我知道如何为排序操作创建索引:how does Mongodb index works?
但我想知道,当我们在a
&上创建联合索引时b
,它与简单索引的工作方式有何不同?
为什么我们只是找到a
会受益,但如果我们找到b
,我们就不会从中获益?联合索引是否就像连接a
& b
,我们会从Prefix获益吗?
答案 0 :(得分:5)
1.但我想知道,当我们在'''''''''''''&#39 >
MongoDB每个查询只使用一个索引..因此,如果您的find()
条件同时包含a
和b
值,则应添加复合索引以有效搜索这两个字段。
2.为什么我们有利于发现' a'但如果我们发现' b' ,我们不会从中得到任何好处吗?联合索引是否就像连接''' b'所以我们会从它获得前缀的好处吗?
MongoDB使用B-tree indexes,因此您只能使用前缀有效地匹配部分密钥。要查找与后缀或子字符串匹配的所有可能值,必须检查所有索引条目。
以下示例使用mongo
shell:
/* Generate some test data */
for (i = 0; i< 1000; i++) {
db.mycoll.insert({a:i})
db.mycoll.insert({b:i})
db.mycoll.insert({a:i,b:i})
}
现在添加一些示例索引:
/* Add simple and compound index */
db.mycoll.ensureIndex({a:1})
db.mycoll.ensureIndex({b:1})
db.mycoll.ensureIndex({a:1, b:1})
最后,对于下面的测试方案,强制您的查询使用$hint
的特定索引并比较explain()
结果。
b
使用b
上的简单索引搜索b
可以直接在索引中找到匹配的条目..它会扫描4个索引条目(nscanned
)以返回4个结果({{ 1}}):
n
db.mycoll.find({b:10}).hint({b:1}).explain()
{
"cursor" : "BtreeCursor b_1",
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 4,
...
}
b
使用(a,b)
上的复合索引搜索b
必须检查索引中的每个(a,b)
值,因为索引的第一部分是{{1的键值}}
所以要直接在索引中查找匹配的条目..它会扫描 1904 索引条目(a
)以返回4个结果(a
):
nscanned
技术上扫描1,904份文件少于我的测试集合中的3,000份文件..但这远非最佳。
n
db.mycoll.find({b:10}).hint({a:1,b:1}).explain()
{
"cursor" : "BtreeCursor a_1_b_1",
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 1904,
...
}
为了进行比较,使用复合索引搜索a
表示只需扫描4个值即可返回4个文档:
(a,b)
对于其他一些示例和解释,我建议您阅读文章Optimizing MongoDB Compound Indexes。