在我看来,我在 MongoDB 查询计划中看到的唯一运算符是 COLLSCAN 或 IXSCAN。索引是b-tree,我猜MongoDB可以做索引搜索和索引扫描?如果是这样,我们怎么知道一个 seek id 执行了?
例如,在这个计划中(只是一个片段):
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 17,
"executionTimeMillis" : 42,
"totalKeysExamined" : 25359,
"totalDocsExamined" : 1553,
"executionStages" : {
"stage" : "FETCH",
"filter" : {
"address.zipcode" : {
"$eq" : "10075"
}
},
"nReturned" : 17,
"executionTimeMillisEstimate" : 30,
"works" : 25360,
"advanced" : 17,
"needTime" : 25342,
"needYield" : 0,
"saveState" : 198,
"restoreState" : 198,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 1553,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"filter" : {
"cuisine" : {
"$regex" : ".*alian",
"$options" : "i"
}
},
"nReturned" : 1553,
"executionTimeMillisEstimate" : 30,
"works" : 25360,
"advanced" : 1553,
"needTime" : 23806,
"needYield" : 0,
"saveState" : 198,
"restoreState" : 198,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"cuisine" : 1.0
},
"indexName" : "cuisine_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"cuisine" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"cuisine" : [
"[\"\", {})",
"[/.*alian/i, /.*alian/i]"
]
},
"keysExamined" : 25359,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0,
"seenInvalidated" : 0
}
我猜这是扫描(我故意进行了正则表达式搜索):
"totalKeysExamined" : 25359,
"totalDocsExamined" : 1553,
但我明白了
"seeks" : 1,
有没有关于如何解释计划的规则,为什么没有 IXSEEK 运算符?
我猜MongoDB可以做索引搜索和索引扫描?
是的,MongoDB 可以进行索引查找和索引扫描,但它可以在一次获取期间同时进行。这就是你的情况。如果从查找索引的最左侧记录开始
cuisine_1
并扫描 25359 个键。在扫描 25359 个键期间,1553 个键与您的搜索条件匹配。索引不是一个覆盖索引,它必须从 1553 个文档中进行查找(对于其他列)。如果是这样,我们怎么知道一个 seek id 执行了?
如果它使用索引,它总是会进行搜索,我想你的问题是它什么时候不做
seek + scan
但只做seek
?IXSCAN意味着:
如果您看到这一点,它将指示寻找一个索引键并且没有扫描。但是任何多于一个的都将表示一个
seek + scan
.当然,当你做正则表达式查询时(以星号开头),我们不能直接做索引扫描,我们需要通过读取所有索引条目。
什么是“寻找”:1 它报告我们必须将 IndexCursor 寻找到新位置以完成索引扫描的次数。
我想只有开发人员/架构师才能回答“为什么没有 IXSEEK”的问题。