为什么带索引的查询不是覆盖查询?
Why is a query with indexes not a covered query?
您想对 example
集合执行覆盖查询。您有以下索引:
{ name : 1, dob : 1 }
{ _id : 1 }
{ hair : 1, name : 1 }
为什么下面的查询不是 covered query?
db.example.find( { name : { $in : [ "Bart", "Homer" ] } }, {_id : 0, hair : 1, name : 1} )
虽然这个是:
db.example.find( { name : { $in : [ "Bart", "Homer" ] } }, {_id : 0, dob : 1, name : 1} )
根据 index prefixes 上的文档,查询
db.example.find( { name : { $in : [ "Bart", "Homer" ] } } );
将被覆盖
db.example.createIndex({ "name": 1, "dob": 1 });
但不是
db.example.createIndex({ "hair": 1, "name": 1 });
因为 { "name": 1 }
不是 { "hair": 1, "name": 1 }
的前缀。
示例
{ "_id": 1, "name": "Bart", "hair": "triangles", "dob": "1985-01-01" }
{ "_id": 2, "name": "Homer", "hair": "two", "dob": "1960-01-01" }
查询 1
> db.example.find(
> { name: { $in: [ "Bart", "Homer" ] } },
> { _id: 0, hair: 1, name: 1 }
> ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined": 2,
"totalDocsExamined": 2,
"executionStages": {
"stage": "PROJECTION",
"inputStage": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"indexName": "name_1_dob_1",
...
如您所见,使用了 name_1_dob_1
索引(因为 { "name": 1 }
是 { "name": 1, "dob": 1 }
的前缀,在索引 ("totalKeysExamined": 2
) 中检查了 2 个文档,并且然后在集合中检查了 2 个文档 ("totalDocsExamined": 2
),因为 name_1_dob_1
索引没有 return.
所需的有关 hair
的信息
查询 2
> db.example.find(
> { name: { $in: [ "Bart", "Homer" ] } },
> { _id: 0, dob: 1, name: 1 }
> ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined": 2,
"totalDocsExamined": 0,
"executionStages": {
"stage": "PROJECTION",
"inputStage": {
"stage": "IXSCAN",
"indexName": "name_1_dob_1",
...
对于查询 1,使用了索引 name_1_dob_1
并在索引中检查了 2 个文档 ("totalKeysExamined": 2
),但没有调用集合 ("totalDocsExamined": 0
) ,因为索引 name_1_dob_1
中同时包含 dob
和 name
,因此无需从集合中获取更多内容。
您想对 example
集合执行覆盖查询。您有以下索引:
{ name : 1, dob : 1 }
{ _id : 1 }
{ hair : 1, name : 1 }
为什么下面的查询不是 covered query?
db.example.find( { name : { $in : [ "Bart", "Homer" ] } }, {_id : 0, hair : 1, name : 1} )
虽然这个是:
db.example.find( { name : { $in : [ "Bart", "Homer" ] } }, {_id : 0, dob : 1, name : 1} )
根据 index prefixes 上的文档,查询
db.example.find( { name : { $in : [ "Bart", "Homer" ] } } );
将被覆盖
db.example.createIndex({ "name": 1, "dob": 1 });
但不是
db.example.createIndex({ "hair": 1, "name": 1 });
因为 { "name": 1 }
不是 { "hair": 1, "name": 1 }
的前缀。
示例
{ "_id": 1, "name": "Bart", "hair": "triangles", "dob": "1985-01-01" }
{ "_id": 2, "name": "Homer", "hair": "two", "dob": "1960-01-01" }
查询 1
> db.example.find(
> { name: { $in: [ "Bart", "Homer" ] } },
> { _id: 0, hair: 1, name: 1 }
> ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined": 2,
"totalDocsExamined": 2,
"executionStages": {
"stage": "PROJECTION",
"inputStage": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN",
"indexName": "name_1_dob_1",
...
如您所见,使用了 name_1_dob_1
索引(因为 { "name": 1 }
是 { "name": 1, "dob": 1 }
的前缀,在索引 ("totalKeysExamined": 2
) 中检查了 2 个文档,并且然后在集合中检查了 2 个文档 ("totalDocsExamined": 2
),因为 name_1_dob_1
索引没有 return.
hair
的信息
查询 2
> db.example.find(
> { name: { $in: [ "Bart", "Homer" ] } },
> { _id: 0, dob: 1, name: 1 }
> ).explain("executionStats");
...
"executionStats": {
"totalKeysExamined": 2,
"totalDocsExamined": 0,
"executionStages": {
"stage": "PROJECTION",
"inputStage": {
"stage": "IXSCAN",
"indexName": "name_1_dob_1",
...
对于查询 1,使用了索引 name_1_dob_1
并在索引中检查了 2 个文档 ("totalKeysExamined": 2
),但没有调用集合 ("totalDocsExamined": 0
) ,因为索引 name_1_dob_1
中同时包含 dob
和 name
,因此无需从集合中获取更多内容。