OPTIONS

FAQ: Indexes

This document addresses common questions regarding MongoDB indexes.

If you don’t find the answer you’re looking for, check the complete list of FAQs or post your question to the MongoDB User Mailing List. See also Indexing Tutorials.

Should you run ensureIndex() after every insert?

No. You only need to create an index once for a single collection. After initial creation, MongoDB automatically updates the index as data changes.

While running ensureIndex() is usually ok, if an index doesn’t exist because of ongoing administrative work, a call to ensureIndex() may disrupt database availability. Running ensureIndex() can render a replica set inaccessible as the index creation is happening. See Build Indexes on Replica Sets.

How do you know what indexes exist in a collection?

To list a collection’s indexes, use the db.collection.getIndexes() method or a similar method for your driver.

How do you determine the size of an index?

To check the sizes of the indexes on a collection, use db.collection.stats().

What happens if an index does not fit into RAM?

When an index is too large to fit into RAM, MongoDB must read the index from disk, which is a much slower operation than reading from RAM. Keep in mind an index fits into RAM when your server has RAM available for the index combined with the rest of the working set.

In certain cases, an index does not need to fit entirely into RAM. For details, see Indexes that Hold Only Recent Values in RAM.

How do you know what index a query used?

To inspect how MongoDB processes a query, use the explain() method in the mongo shell, or in your application driver.

How do you determine what fields to index?

A number of factors determine what fields to index, including selectivity, fitting indexes into RAM, reusing indexes in multiple queries when possible, and creating indexes that can support all the fields in a given query. For detailed documentation on choosing which fields to index, see Indexing Tutorials.

How do write operations affect indexes?

Any write operation that alters an indexed field requires an update to the index in addition to the document itself. If you update a document that causes the document to grow beyond the allotted record size, then MongoDB must update all indexes that include this document as part of the update operation.

Therefore, if your application is write-heavy, creating too many indexes might affect performance.

Will building a large index affect database performance?

Building an index can be an IO-intensive operation, especially if you have a large collection. This is true on any database system that supports secondary indexes, including MySQL. If you need to build an index on a large collection, consider building the index in the background. See Index Creation.

If you build a large index without the background option, and if doing so causes the database to stop responding, do one of the following:

  • Wait for the index to finish building.
  • Kill the current operation (see db.killOp()). The partial index will be deleted.

Can I use index keys to constrain query matches?

You can use the min() and max() methods to constrain the results of the cursor returned from find() by using index keys.

Using $ne and $nin in a query is slow. Why?

The $ne and $nin operators are not selective. See Create Queries that Ensure Selectivity. If you need to use these, it is often best to make sure that an additional, more selective criterion is part of the query.

Can I use a multi-key index to support a query for a whole array?

Not entirely. The index can partially support these queries because it can speed the selection of the first element of the array; however, comparing all subsequent items in the array cannot use the index and must scan the documents individually.

How can I effectively use indexes strategy for attribute lookups?

For simple attribute lookups that don’t require sorted result sets or range queries, consider creating a field that contains an array of documents where each document has a field (e.g. attrib ) that holds a specific type of attribute. You can index this attrib field.

For example, the attrib field in the following document allows you to add an unlimited number of attributes types:

{ _id : ObjectId(...),
  attrib : [
            { k: "color", v: "red" },
            { k: "shape": v: "rectangle" },
            { k: "color": v: "blue" },
            { k: "avail": v: true }
           ]
}

Both of the following queries could use the same { "attrib.k": 1, "attrib.v": 1 } index:

db.mycollection.find( { attrib: { $elemMatch : { k: "color", v: "blue" } } } )
db.mycollection.find( { attrib: { $elemMatch : { k: "avail", v: true } } } )