Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongodb not using indexes when sorting?

i have a collection with these indexes:

> db.message.getIndexKeys()
[
    {
        "_id" : 1
    },
    {
        "msgid" : 1
    },
    {
        "keywords" : 1,
        "msgid" : 1
    }
]

and a query like

db.message.find({'keywords': {'$all': ['apple', 'banana']}}).limit(30).explain()

works fine with index

{
    "cursor" : "BtreeCursor keywords_1_msgid_1",    
    "nscanned" : 96,
    "nscannedObjects" : 96,
    ...
}

but when sorting with msgid:

db.message.find({'keywords': {'$all': ['apple', 'banana']}})
    .sort({msgid:-1})
    .limit(30).explain()

mongodb do not use indexes any more:

{
"cursor" : "BtreeCursor msgid_1 reverse",
"nscanned" : 1784455,
"nscannedObjects" : 1784455,
...
}

any solutions?

like image 354
Bearice Avatar asked Dec 09 '11 03:12

Bearice


People also ask

Does sort use index MongoDB?

MongoDB may use multiple indexes to support a sort operation if the sort uses the same indexes as the query predicate. If MongoDB cannot use an index or indexes to obtain the sort order, MongoDB must perform a blocking sort operation on the data.

Why index is not used in MongoDB?

Indexes support the efficient execution of queries in MongoDB. Without indexes, MongoDB must perform a collection scan, i.e. scan every document in a collection, to select those documents that match the query statement.

How does MongoDB sort data?

To sort documents in MongoDB, you need to use sort() method. The method accepts a document containing a list of fields along with their sorting order. To specify sorting order 1 and -1 are used. 1 is used for ascending order while -1 is used for descending order.

Are indexes stored in memory MongoDB?

Indexes are stored in memory, are kept in sorted order, and prevent queries from having to scan every document in a collection when querying an indexed field.


2 Answers

Mongo actually is using an index (which you can tell by seeing BtreeCursor in the explain), just not the compound one.

It's important to keep in mind that direction matters when you have a compound index.

Try: db.ensureIndex({ keywords: 1, msg_id: -1 })

Mongo chooses to use msg_id index in reverse in your example because its faster to retrieve the results in sorted order and then match in O(n) time than to match the results and then sort in O(nlogn) time.

like image 148
Tyler Brock Avatar answered Sep 18 '22 22:09

Tyler Brock


It is using an index -- the index on msgid. MongoDB chooses an index to use for a query by trying all possible indexes, and using whichever one finishes first. This result is cached for 1,000 queries, or until a certain number of modifications to the collection are made (data changes, new indexes, etc).

You can see all the query plans tried by passing true to explain().

For more details, see http://www.mongodb.org/display/DOCS/Query+Optimizer.

like image 33
dcrosta Avatar answered Sep 18 '22 22:09

dcrosta