在这个问题的注释中,我知道如何为排序操作创建索引:Mongodb索引是如何工作的?
a & b上创建一个联合索引时,它与一个简单的索引有何不同?a中受益,但是如果我们找到了b,我们就得不到任何好处?联合索引是否像连接a和b,那么前缀就能从中获益吗?发布于 2012-11-04 04:18:28
1.但我想知道,当我们在“a”和“b”上创建一个联合索引时,它与简单的索引有何不同?
MongoDB只对每个查询使用一个索引。因此,如果您的find()条件同时包含a和b值,则应该添加一个复合索引以有效地搜索这两个字段。
2.为什么我们只会找到'a‘,而如果我们找到'b’,我们就不会从中得到任何好处?是否联合索引就像连接‘a’和‘b’,这样我们就能从它得到好处作为前缀吗?
MongoDB使用B树索引,因此只能使用前缀有效地匹配部分键。若要查找与后缀或子字符串匹配的所有可能值,必须检查所有索引项。
设置测试数据以进行比较
下面的例子是使用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个结果(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)必须检查索引中的每个a值,因为索引的第一部分是a的键值。
因此,要在索引中直接查找匹配项。它扫描1904索引条目(nscanned)以返回4个结果(n):
db.mycoll.find({b:10}).hint({a:1,b:1}).explain()
{
"cursor" : "BtreeCursor a_1_b_1",
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 1904,
...
}从技术上讲,扫描1,904份文档的数量少于我的测试集合中的3,000份。但这远非最佳方案。
使用复合索引a搜索(a,b)
比较而言,使用复合索引对a进行搜索显示,只需扫描4个值即可返回4个文档:
db.mycoll.find({a:10}).hint({a:1,b:1}).explain()
{
"cursor" : "BtreeCursor a_1_b_1",
"n" : 4,
"nscannedObjects" : 4,
"nscanned" : 4,
"nscannedObjectsAllPlans" : 4,
...
}关于进一步的示例和解释,我建议您阅读MongoDB复合指标的优化一篇文章。
https://stackoverflow.com/questions/13215401
复制相似问题