我看了this并尝试了一次。但它没有工作,我无法在winsPlan或rejectedPlans(mongodb 3.6)中看到任何索引交叉计划。当我搜索问题时,我遇到了answer。所以我完全模仿了问题中发布的内容:
代码:
for(var i=0;i<100;i++){
for(var j=0;j<100;j++){
db.t.insert({item:"abc"+i,qty:j})
}
}
索引:
db.t.createIndex({qty:1})
db.t.createIndex({item:1});
查询:
db.t.explain().find({item:"abc123",qty:{$gt:15}});
结果:
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"qty" : {
"$gt" : 15
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"item" : 1
},
"indexName" : "item_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"item" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"item" : [
"[\"abc123\", \"abc123\"]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH",
"filter" : {
"item" : {
"$eq" : "abc123"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"qty" : 1
},
"indexName" : "qty_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"qty" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"qty" : [
"(15.0, inf.0]"
]
}
}
}
]
mongodb没有看到任何索引交叉尝试的迹象。但是,以下查询会在AND_SORTED
中显示rejectedPlans
阶段:
db.t.explain().find({item:"abc123",qty:15});
我在文档中找不到mongodb的任何变化吗?有人可以帮助我解决我在这里失踪的问题。
答案 0 :(得分:1)
交叉点不适用于远程查询,除非它在v3.6中发生了显着变化。来自旧https://jira.mongodb.org/browse/SERVER-3071?focusedCommentId=508454&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-508454:
答:查询优化器可能选择索引交叉点计划 以下条件成立:
- 相关集合中的大多数文档都是磁盘驻留的。 索引交集的优点是它可以避免获取 当交叉点的大小很小时完整的文档。如果 文件已经在记忆中,通过避免没有任何好处 取。
- 查询谓词是单点间隔,而不是 范围谓词或一组间隔。单点查询 interval返回按磁盘位置排序的文件,允许 优化器选择计算a中交集的计划 无阻碍的时尚。这通常比替代方案更快 计算交集的模式,即构建哈希表 用一个索引的结果,然后用结果探测它 来自第二个指数。
- 两个要交叉的指数都不是 高度选择性。如果其中一个指数是选择性的那么 优化器将选择一个只扫描此选择性索引的计划。
- 相对于索引的数量,交点的大小较小 由单索引解决方案扫描的密钥。在这种情况下查询 执行者可以使用索引查看较小的文档集 交叉,可能让我们获得更少的好处 从磁盘中提取。