Saturday 21 February 2015

Hinting an index


mongoDb hint() method is used to override MongoDB’s default index selection and query optimization process.

Let’s say, below students collection has indexes on “first_name”, “last_name” and “first_name”, “last_name”.

> db.students.getIndexes()
[
        {
                "v" : 1,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "school.students"
        },
        {
                "v" : 1,
                "key" : {
                        "last_name" : 1
                },
                "name" : "last_name_1",
                "ns" : "school.students"
        },
        {
                "v" : 1,
                "key" : {
                        "first_name" : 1
                },
                "name" : "first_name_1",
                "ns" : "school.students"
        },
        {
                "v" : 1,
                "key" : {
                        "first_name" : 1,
                        "last_name" : 1
                },
                "name" : "first_name_1_last_name_1",
                "ns" : "school.students"
        }
]
>
>
>
> db.students.find({"first_name": "first_name1"}).explain()
{
        "cursor" : "BtreeCursor first_name_1",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 1,
        "nscanned" : 1,
        "nscannedObjectsAllPlans" : 2,
        "nscannedAllPlans" : 2,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 1,
        "nChunkSkips" : 0,
        "millis" : 285,
        "indexBounds" : {
                "first_name" : [
                        [
                                "first_name1",
                                "first_name1"
                        ]
                ]
        },
        "server" : "RENT-MIS-LT3016:27017",
        "filterSet" : false
}

As you observe, mongoDB uses the index “first_name”. If you want to force mongoDB to use index on “last_name”, use hint command like below.
> db.students.find({"first_name": "first_name1"}).hint({"last_name":1}).explain()
{
        "cursor" : "BtreeCursor last_name_1",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 10000000,
        "nscanned" : 10000000,
        "nscannedObjectsAllPlans" : 10000000,
        "nscannedAllPlans" : 10000000,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 78147,
        "nChunkSkips" : 0,
        "millis" : 32239,
        "indexBounds" : {
                "last_name" : [
                        [
                                {
                                        "$minElement" : 1
                                },
                                {
                                        "$maxElement" : 1
                                }
                        ]
                ]
        },
        "server" : "RENT-MIS-LT3016:27017",
        "filterSet" : false
}

You can observe above query takes more time than the original one, it is because we are searching on “first_name” using the index on “last_name”.

If you want to use default index, then use {natural:1} as hint parameter.

> db.students.find({"first_name": "first_name1"}).hint({$natural:1}).explain()
{
        "cursor" : "BasicCursor",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 10000000,
        "nscanned" : 10000000,
        "nscannedObjectsAllPlans" : 10000000,
        "nscannedAllPlans" : 10000000,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 78125,
        "nChunkSkips" : 0,
        "millis" : 5591,
        "server" : "RENT-MIS-LT3016:27017",
        "filterSet" : false
}

Prevoius                                                 Next                                                 Home

No comments:

Post a Comment