以下哪个查询将使用索引?
Which of the following queries will use the index?
给定集合 foo
具有以下索引:
db.foo.createIndex( { a : 1, b : 1, c : 1 } )
我们需要select以下哪些查询将使用索引?
db.foo.find( { c : 1 } ).sort( { a : -1, b : 1 } )
db.foo.find( { b : 3, c : 4 } )
db.foo.find( { a : 3 } )
db.foo.find( { c : 1 } ).sort( { a : 1, b : 1 } )
我很惊讶 3、4 是正确的选项,1、2 不是。
为什么下面的查询会用到索引?
db.foo.find( { a : 3 } )
这似乎可以使用索引但是_id
没有投影出来。
db.foo.find( { c : 1 } ).sort( { a : 1, b : 1 } )
我们正在寻找位于索引右侧的c
为什么下面的查询会"not"使用索引?
db.foo.find( { c : 1 } ).sort( { a : -1, b : 1 } )
db.foo.find( { b : 3, c : 4 } )
关于第一个问题:db.foo.find( { c : 1 } ).sort( { a : -1, b : 1 } )
方向很重要,这里有更多信息
why does direction of index matter in MongoDB?.
你可以看看 http://openmymind.net/mongodb.pdf => 第 56 页
关于第二个。索引中定义的键的顺序也很重要。
这里有更多信息 =>
查询 1
db.foo.find( { c: 1 } ).sort( { a: -1, b: 1 } );
使用 { c: 1 }
过滤将不会使用索引,因为 { c: 1 }
不是 { a: 1, b: 1, c: 1 }
(documentation). Sorting with { a: -1, b: 1 }
will not use the index, since sort direction (1 or -1) does matter (documentation) 的前缀。
查询 2
db.foo.find( { b: 3, c: 4 } );
使用 { b: 3, c: 4 }
过滤将不会使用索引,因为 { b: 1, c: 1 }
不是 { a: 1, b: 1, c: 1 }
的前缀。
查询 3
db.foo.find( { a: 3 } );
使用 { a: 3 }
过滤将使用索引,因为 { a: 1 }
是 { a: 1, b: 1, c: 1 }
的前缀。
This seems to be able to use the index however _id is not projected
out.
字段 _id
将在查询结果中,除非您指定相反。
对于文档 { _id: 1, a: 3, b: 4, c: 5 }
考虑下一个查询及其结果
> db.foo.find( { a: 3 }, { _id: 0, a: 1, b: 1, c: 1 } );
{ "a": 3, "b": 4, "c": 5 }
> db.foo.find( { a: 3 }, { a: 1 } ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined" : 1,
"totalDocsExamined" : 0,
...
> db.foo.find( { a: 3 } );
{ "_id": 0, "a": 3, "b": 4, "c": 5 }
> db.foo.find( { a: 3 } ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined": 1,
"totalDocsExamined": 1,
...
请注意,在第二种情况下,文档的 _id
是在索引扫描后从集合 ("totalDocsExamined": 1
) 中提取的,因为查询并未说明 _id
字段不是必需的结果。
查询 4
db.foo.find( { c: 1 } ).sort( { a: 1, b: 1 } );
使用 { a: 1, b: 1 }
排序将使用索引,因为 { a: 1, b: 1 }
是 { a: 1, b: 1, c: 1 }
的前缀子集(对于非前缀子集 - 请参阅 documentation) and sort keys are listed in the same order, direction as in the { a: 1, b: 1, c: 1 }
(documentation)。但是,索引不会用于过滤,因为 { c: 1 }
不是 { a: 1, b: 1, c: 1 }
的前缀。考虑下一个查询及其结果
> db.foo.find( { c: 1 }, { _id: 0 } ).sort( { a: 1, b: 1 } ).explain("executionStats");
...
"executionStages": {
"stage": "FETCH",
"filter": {
"c": { "$eq": 3 } // filtering is done by fetching from the collection
},
"inputStage": {
"stage": "IXSCAN",
"indexBounds": {
"a": [ "[MINKEY, MAXKEY]" ],
"b": [ "[MINKEY, MAXKEY]" ],
"c": [ "[MINKEY, MAXKEY]" ] // index was not used for filtering c
}
...
> db.foo.find( { a: 1 }, { _id: 0 } ).sort( { a: 1, b: 1 } ).explain("executionStats");
...
"executionStages": {
"stage": "PROJECTION",
"inputStage": {
"stage": "IXSCAN",
"indexBounds": {
"a": [ "[3.0, 3.0]" ], // index was used for filtering a
"b": [ "[MINKEY, MAXKEY]" ],
"c": [ "[MINKEY, MAXKEY]" ]
}
...
请注意,在第二种情况下,过滤和排序都是使用索引完成的,并且没有调用集合。
给定集合 foo
具有以下索引:
db.foo.createIndex( { a : 1, b : 1, c : 1 } )
我们需要select以下哪些查询将使用索引?
db.foo.find( { c : 1 } ).sort( { a : -1, b : 1 } )
db.foo.find( { b : 3, c : 4 } )
db.foo.find( { a : 3 } )
db.foo.find( { c : 1 } ).sort( { a : 1, b : 1 } )
我很惊讶 3、4 是正确的选项,1、2 不是。
为什么下面的查询会用到索引?
db.foo.find( { a : 3 } )
这似乎可以使用索引但是_id
没有投影出来。
db.foo.find( { c : 1 } ).sort( { a : 1, b : 1 } )
我们正在寻找位于索引右侧的c
为什么下面的查询会"not"使用索引?
db.foo.find( { c : 1 } ).sort( { a : -1, b : 1 } )
db.foo.find( { b : 3, c : 4 } )
关于第一个问题:db.foo.find( { c : 1 } ).sort( { a : -1, b : 1 } )
方向很重要,这里有更多信息 why does direction of index matter in MongoDB?.
你可以看看 http://openmymind.net/mongodb.pdf => 第 56 页
关于第二个。索引中定义的键的顺序也很重要。
这里有更多信息 =>
查询 1
db.foo.find( { c: 1 } ).sort( { a: -1, b: 1 } );
使用 { c: 1 }
过滤将不会使用索引,因为 { c: 1 }
不是 { a: 1, b: 1, c: 1 }
(documentation). Sorting with { a: -1, b: 1 }
will not use the index, since sort direction (1 or -1) does matter (documentation) 的前缀。
查询 2
db.foo.find( { b: 3, c: 4 } );
使用 { b: 3, c: 4 }
过滤将不会使用索引,因为 { b: 1, c: 1 }
不是 { a: 1, b: 1, c: 1 }
的前缀。
查询 3
db.foo.find( { a: 3 } );
使用 { a: 3 }
过滤将使用索引,因为 { a: 1 }
是 { a: 1, b: 1, c: 1 }
的前缀。
This seems to be able to use the index however _id is not projected out.
字段 _id
将在查询结果中,除非您指定相反。
对于文档 { _id: 1, a: 3, b: 4, c: 5 }
考虑下一个查询及其结果
> db.foo.find( { a: 3 }, { _id: 0, a: 1, b: 1, c: 1 } );
{ "a": 3, "b": 4, "c": 5 }
> db.foo.find( { a: 3 }, { a: 1 } ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined" : 1,
"totalDocsExamined" : 0,
...
> db.foo.find( { a: 3 } );
{ "_id": 0, "a": 3, "b": 4, "c": 5 }
> db.foo.find( { a: 3 } ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined": 1,
"totalDocsExamined": 1,
...
请注意,在第二种情况下,文档的 _id
是在索引扫描后从集合 ("totalDocsExamined": 1
) 中提取的,因为查询并未说明 _id
字段不是必需的结果。
查询 4
db.foo.find( { c: 1 } ).sort( { a: 1, b: 1 } );
使用 { a: 1, b: 1 }
排序将使用索引,因为 { a: 1, b: 1 }
是 { a: 1, b: 1, c: 1 }
的前缀子集(对于非前缀子集 - 请参阅 documentation) and sort keys are listed in the same order, direction as in the { a: 1, b: 1, c: 1 }
(documentation)。但是,索引不会用于过滤,因为 { c: 1 }
不是 { a: 1, b: 1, c: 1 }
的前缀。考虑下一个查询及其结果
> db.foo.find( { c: 1 }, { _id: 0 } ).sort( { a: 1, b: 1 } ).explain("executionStats");
...
"executionStages": {
"stage": "FETCH",
"filter": {
"c": { "$eq": 3 } // filtering is done by fetching from the collection
},
"inputStage": {
"stage": "IXSCAN",
"indexBounds": {
"a": [ "[MINKEY, MAXKEY]" ],
"b": [ "[MINKEY, MAXKEY]" ],
"c": [ "[MINKEY, MAXKEY]" ] // index was not used for filtering c
}
...
> db.foo.find( { a: 1 }, { _id: 0 } ).sort( { a: 1, b: 1 } ).explain("executionStats");
...
"executionStages": {
"stage": "PROJECTION",
"inputStage": {
"stage": "IXSCAN",
"indexBounds": {
"a": [ "[3.0, 3.0]" ], // index was used for filtering a
"b": [ "[MINKEY, MAXKEY]" ],
"c": [ "[MINKEY, MAXKEY]" ]
}
...
请注意,在第二种情况下,过滤和排序都是使用索引完成的,并且没有调用集合。