hal*_*ack 1 indexing mongodb mongodb-indexes
在这个问题的评论中,我知道如何为排序操作创建索引:Mongodb索引如何工作?
但我想知道,当我们在a&上创建联合索引时b,它与简单索引的工作方式有何不同?
为什么我们只是在寻找中受益a,但如果我们发现b,我们没有从中获益?无论是联合索引就像是串联a和b,所以我们会得到好处,从它的前缀?
但是我想知道,当我们在'a'和'b'上创建一个联合索引时,它与简单索引有什么区别?
MongoDB每个查询只使用一个索引.因此,如果您的find()条件包含both a和bvalues,则应添加复合索引以有效搜索这两个字段.
2.为什么我们会好好找到'a',但如果我们找到'b',我们就不会从中得到任何好处?联合索引是否就像连接'a'和'b'一样,所以我们将从它获得前缀的好处?
MongoDB使用B树索引,因此您只能使用前缀有效地匹配部分密钥.要查找与后缀或子字符串匹配的所有可能值,必须检查所有索引条目.
以下示例使用mongoshell:
/* 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})
}
Run Code Online (Sandbox Code Playgroud)
现在添加一些示例索引:
/* Add simple and compound index */
db.mycoll.ensureIndex({a:1})
db.mycoll.ensureIndex({b:1})
db.mycoll.ensureIndex({a:1, b:1})
Run Code Online (Sandbox Code Playgroud)
最后,对于下面的测试场景,强制您的查询使用特定索引$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,
...
}
Run Code Online (Sandbox Code Playgroud)
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,
...
}
Run Code Online (Sandbox Code Playgroud)
技术上扫描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,
...
}
Run Code Online (Sandbox Code Playgroud)
对于一些进一步的示例和解释,我建议阅读文章Optimizing MongoDB Compound Indexes.
| 归档时间: |
|
| 查看次数: |
419 次 |
| 最近记录: |