为什么Mongo查询会忽略索引

时间:2019-07-20 11:37:54

标签: mongodb

我的mongo集合中有两个索引

[{
  "v" : 1,
  "key" : {
    "updated" : 1,
    "type" : 1
  },
  "name" : "index_1",
  "ns" : "abacus.cps"
},
{
  "v" : 1,
  "key" : {
    "type" : 1,
    "site_name" : 1,
    "language" : 1,
    "firstPublished" : -1,
    "wordcount" : 1
  },
  "name" : "index_2",
  "ns" : "abacus.cps"
}]

当我使用以下查询数据库时

db.cps.find({ updated: { $gte: new Date(1563104071535) }, type: "STY"}).explain()

它偏爱index_2。即使我使用index_1强制查询使用hint(),它的性能仍然很差。我对如何使该索引和查询性能产生误解。

编辑1:更新了解释结果

{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "abacus.cps",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "$and" : [
                {
                    "type" : {
                        "$eq" : ""
                    }
                },
                {
                    "updated" : {
                        "$gte" : ISODate("2019-07-14T11:34:31.535Z")
                    }
                }
            ]
        },
        "winningPlan" : {
            "stage" : "FETCH",
            "filter" : {
                "updated" : {
                    "$gte" : ISODate("2019-07-14T11:34:31.535Z")
                }
            },
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "type" : 1,
                    "site_name" : 1,
                    "language" : 1,
                    "firstPublished" : -1,
                    "wordcount" : 1
                },
                "indexName" : "type_1_site_name_1_language_1_firstPublished_-1_wordcount_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "type" : [ ],
                    "site_name" : [ ],
                    "language" : [ ],
                    "firstPublished" : [ ],
                    "wordcount" : [ ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 1,
                "direction" : "forward",
                "indexBounds" : {
                    "type" : [
                        "[\"\", \"\"]"
                    ],
                    "site_name" : [
                        "[MinKey, MaxKey]"
                    ],
                    "language" : [
                        "[MinKey, MaxKey]"
                    ],
                    "firstPublished" : [
                        "[MaxKey, MinKey]"
                    ],
                    "wordcount" : [
                        "[MinKey, MaxKey]"
                    ]
                }
            }
        },
        "rejectedPlans" : [
            {
                "stage" : "FETCH",
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "updated" : 1,
                        "type" : 1
                    },
                    "indexName" : "updated_1_type_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "updated" : [ ],
                        "type" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 1,
                    "direction" : "forward",
                    "indexBounds" : {
                        "updated" : [
                            "[new Date(1563104071535), new Date(9223372036854775807)]"
                        ],
                        "type" : [
                            "[\"\", \"\"]"
                        ]
                    }
                }
            }
        ]
    },
    "ok" : 1
}

1 个答案:

答案 0 :(得分:1)

之所以选择索引2优于索引1的原因是,在索引1中,第一个字段是“更新的”,而您正在对“更新的”字段使用范围查询($ gte)。

虽然索引2具有第一个字段“ type”,但是您正在对字段“ type”执行相等性查询。平等优先于范围操作。

您的索引1应该按顺序排列:

{
    "type" : 1,
    "updated" : 1
}