为什么带索引的查询不是覆盖查询?

时间:2016-09-04 14:29:30

标签: mongodb indexing mongodb-query query-optimization

您希望对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} )

1 个答案:

答案 0 :(得分:3)

根据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信息,因此在集合(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,并在索引("totalKeysExamined": 2)中检查了2个文档,但没有调用集合("totalDocsExamined": 0),因为index name_1_dob_1中包含dobname,并且无需从集合中获取更多内容。