Search code examples
mongodbcompound-index

mongodb compound index over extending


I have a question regarding compound indexes that i cant seem to find, or maybe just have misunderstood.

Lets say i have created a compound index {a:1, b:1, c:1}. This should make according to http://docs.mongodb.org/manual/core/indexes/#compound-indexes

the following queries fast.

db.test.find({a:"a", b:"b",c:"c"})
db.test.find({a:"a", b:"b"})
db.test.find({a:"a"})

As i understand it the order of the query is very important, but is it only that explicit subset of {a:"a", b:"b",c:"c"} order that is important?

Lets say i do a query

db.test.find({d:"d",e:"e",a:"a", b:"b",c:"c"})

or

db.test.find({a:"a", b:"b",c:"c",d:"d",e:"e"})

Will these render useless for that specific compound index?


Solution

  • Compound indexes in MongoDB work on a prefix mechanism whereby a and {a,b} would be considered prefixes, by order, of the compound index, however, the order of the fields in the query itself do not normally matter.

    So lets take your examples:

    db.test.find({d:"d",e:"e",a:"a", b:"b",c:"c"})
    

    Will actually use an index:

    db.ghghg.find({d:1,e:1,a:1,c:1,b:1}).explain()
    {
            "cursor" : "BtreeCursor a_1_b_1_c_1",
            "isMultiKey" : false,
            "n" : 1,
            "nscannedObjects" : 1,
            "nscanned" : 1,
            "nscannedObjectsAllPlans" : 2,
            "nscannedAllPlans" : 2,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nYields" : 0,
            "nChunkSkips" : 0,
            "millis" : 0,
            "indexBounds" : {
                    "a" : [
                            [
                                    1,
                                    1
                            ]
                    ],
                    "b" : [
                            [
                                    1,
                                    1
                            ]
                    ],
                    "c" : [
                            [
                                    1,
                                    1
                            ]
                    ]
            },
            "server" : "ubuntu:27017"
    }
    

    Since a and b are there.

    db.test.find({a:"a", b:"b",c:"c",d:"d",e:"e"})
    

    Depends upon the selectivity and cardinality of d and e. It will use the compound index but as to whether it will use it effectively in a such a manner that allows decent performance of the query depends heavily upon what's in there.