dmo
dmo

Reputation: 5321

Why does Mongo query ignore index

I have two indexes in my mongo collection

[{
  "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"
}]

When I query the db with the following

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

It favours index_2. Even if I force the query to use index_1 using hint() it still performs badly. Is there something I am misunderstanding on how to make this index and query performant.

Edit 1: Updated with Explain results

{
    "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
}

Upvotes: 0

Views: 478

Answers (1)

Rajat Goel
Rajat Goel

Reputation: 2305

The reason why index 2 is favored over index 1 is that in index 1, the first field is "updated" and you are using range query ($gte) on "updated" field.

While index 2 has first field "type", and you are performing equality query on the field "type". Equality has more preference than range operations.

Your index 1 should be in order:

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

Upvotes: 2

Related Questions