1

Couldn't find a good answer for my question - do you think an index on a collection that will only run findOne query help with performance? I understand that index is used to avoid scanning through entire collection when running find query. However, in a findOne query, does index provide any benefit?

For example, in users collection, let's assume it only has one field - username. Does index on username improve db.users.findOne({username: 'johndoe'})?

Grokify
  • 15,092
  • 6
  • 60
  • 81
amkay
  • 13
  • 6

1 Answers1

1

Yes. An index will still help if you are searching a single field. They are useful for single field searches, not just compound searches.

If you want to avoid creating an index, and your username is unique, you can consider using the username as the _id property. If you consider this, be sure to read up on partitioning and key distribution.

For higher performance, you read check out this information on a Covered Query, which necessitates that all the fields you are retrieving are also indexed. The following from MongoDB's docs explains this.

Covered Query

A covered query is a query that can be satisfied entirely using an index and does not have to examine any documents. An index covers a query when both of the following apply:

  • all the fields in the query are part of an index, and
  • all the fields returned in the results are in the same index.

Performance

Because the index contains all fields required by the query, MongoDB can both match the query conditions and return the results using only the index.

Querying only the index can be much faster than querying documents outside of the index. Index keys are typically smaller than the documents they catalog, and indexes are typically available in RAM or located sequentially on disk.

Of note, if you just want to check if a record exists, find().limit(1) is significantly faster than findOne because find().limit(1) returns a cursor while findOne() will read the document, return it to you, and close the cursor if the record exists. When using find().limit(1), no query is executed so you will need another action to initiate a query like size() or count(true).

Here is some info from a MongoDB engineer:

The two queries you are executing are very different. A find query returns a cursor, this is essentially a no-operation scenario, as no actual data is returned (only the cursor information). If you call findOne, then you are actually returning the data and closing the cursor. The docs should definitely be clearer :-)

Some additional information with discussion of these queries:

Grokify
  • 15,092
  • 6
  • 60
  • 81