首页 > 解决方案 > 为什么Mongo查询忽略索引

问题描述

我的 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
}

标签: mongodb

解决方案


索引 2 优于索引 1 的原因是在索引 1 中,第一个字段是“更新的”,并且您在“更新”字段上使用范围查询 ($gte)。

虽然索引 2 具有第一个字段“类型”,但您正在对字段“类型”执行相等查询。平等比范围操作更偏爱。

您的索引 1 应该是有序的:

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

推荐阅读