Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongodb not using indexes

Tags:

mongodb

nosql

I have a collection with these indexes:

db.colaboradores.getIndexKeys()
[ { "_id" : 1 }, { "nome" : 1 }, { "sobrenome" : 1 } ]

and a query like

db.colaboradores.find({_id: ObjectId("5040e298914224dca3000006")}).explain();

thatworks fine with index

{
    "cursor" : "BtreeCursor _id_",
    "nscanned" : 0,
    "nscannedObjects" : 0,
    "n" : 0,
    "millis" : 0,
}

but when run:

db.colaboradores.find({nome: /^Administrador/}).explain()

mongodb do not use indexes any more:

{
    "cursor" : "BtreeCursor nome_1",
    "nscanned" : 10000,
    "nscannedObjects" : 10000,
    "n" : 10000,
    "millis" : 25,
}

any solutions? Thanks!

like image 982
user1639326 Avatar asked Aug 31 '12 17:08

user1639326


People also ask

Do you need indexes 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.

Does MongoDB automatically index?

Each collection in MongoDB automatically has an index on the _id field. This index can then be used to fetch documents from the database efficiently. However, you will need to query data on other specific fields most of the time. This is where a single field index will come in handy.

How do I know if my MongoDB index is working?

In MongoDB, you can use the cursor. explain() method or the db. collection. explain() method to determine whether or not a query uses an index.

Does MongoDB index all fields?

MongoDB provides complete support for indexes on any field in a collection of documents. By default, all collections have an index on the _id field, and applications and users may add additional indexes to support important queries and operations. This document describes ascending/descending indexes on a single field.


2 Answers

The behaviour you're seeing is expected from MongoDB. This is generally true for any query where you are using a compound index -- one with multiple fields.

The rules of thumb are:

If you have an index on {a:1, b:1, c:1}, then the following queries will be able to use the index efficiently:

find(a)
find(a,b)
find(a,b,c)
find(a).sort(a)
find(a).sort(b)
find(a,b).sort(b)
find(a,b).sort(c)

However, the following queries will not be able to take full advantage of the index:

find(b)
find(c)
find(b,c)
find(b,c).sort(a)

The reason is the way that MongoDB creates compound indexes. The indexes are btrees, and the nodes are present in the btree in sorted order, with the left-most field being the major sort, the next field being the secondary sort, and so on.

If you skip the leading member of the index, then the index traversal will have to skip lots of blocks. If that performance is slow, then the query optimizer will choose to use a full-collection scan rather than use the index.

For more information about MongoDB indexes, see this excellent article here:

  • http://kylebanker.com/blog/2010/09/21/the-joy-of-mongodb-indexes/
like image 101
William Z Avatar answered Oct 01 '22 09:10

William Z


It did use an index - you can tell because the cursor was a BtreeCursor. You have a lot (10000) of documents in your collection where 'nome' equals 'Administrador'.

An explanation of the output:

"cursor" : "Btree_Cursor nome_1" means that the database used an ascending index on "nome" to satisfy the query. If no index were used, the cursor would be "BasicCursor".

"nscanned" : The number of documents that the database had to check ("nscannedObjects" is basically the same thing for this query)

"n" : The number of documents returned. The fact that this is the same as "nscanned" means that the index is efficient - it didn't have to check any documents that didn't match the query.

like image 21
shelman Avatar answered Oct 01 '22 07:10

shelman