【问题标题】:Why is a query with indexes not a covered query?为什么带有索引的查询不是覆盖查询?
【发布时间】:2017-01-12 01:55:06
【问题描述】:

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

【问题讨论】:

  • 感谢您发布这个问题。我在 M101JS 遇到了同样的问题。讲师在创建索引时没有谈论字段的顺序,并且在答案的“解释”中,他只是通过将其称为“左子集”来非常简要地提到了这个想法......他似乎是一个术语已经和好了。
  • @Vince 我很高兴它有帮助...

标签: mongodb indexing mongodb-query query-optimization


【解决方案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 } 的前缀,因此在索引中检查了2 个文档("totalKeysExamined": 2),然后在集合中检查了2 个文档(@ 987654333@),因为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),因为索引 name_1_dob_1 包含两者dobname 在其中,无需从集合中获取更多内容。

【讨论】:

  • 谢谢,祝你幸福:)
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 1970-01-01
相关资源
最近更新 更多