11. Indexes and performance

Indexes dramatically improve query performance.

What is an index?

An index is a special data structure that stores a small portion of the data in a way that is easy to traverse. It is like the index of a book.

Without an index, MongoDB must scan the entire collection (collection scan). With an index, MongoDB can go directly to the relevant documents.

Viewing indexes

To see the indexes of a collection:

db.unicorns.getIndexes()

By default, all collections have an index on _id.

Creating indexes

To create a simple index:

// Index on the name field
db.unicorns.createIndex({ name: 1 })
  • 1 = ascending order
  • -1 = descending order

For simple indexes, the order doesn't matter. For compound indexes, it does.

Compound indexes

You can create indexes on multiple fields:

db.unicorns.createIndex({ gender: 1, vampires: -1 })

This index is useful for queries that filter by gender and/or sort by vampires.

Unique indexes

To guarantee there are no duplicates:

db.users.createIndex({ email: 1 }, { unique: true })

Now you won't be able to insert two users with the same email.

Removing indexes

To remove an index:

db.unicorns.dropIndex({ name: 1 })

To remove all indexes except _id:

db.unicorns.dropIndexes()

Analyzing queries with explain

To see whether a query uses indexes:

db.unicorns.explain().find({ name: 'Aurora' })

Look for the winningPlan field:

  • COLLSCAN = full scan (bad, slow)
  • IXSCAN = uses index (good, fast)

Indexes on arrays

You can create indexes on fields that are arrays:

db.unicorns.createIndex({ loves: 1 })

This creates a multikey index that indexes each value in the array.

Indexes on embedded fields

You can create indexes on fields of embedded documents:

db.users.createIndex({ 'address.city': 1 })

Note the dot notation in quotes.

When to create indexes

Create indexes when:

  • Slow queries: if a query takes too long
  • Search fields: if you frequently filter by a field
  • Sorting: if you frequently sort by a field

Don't create unnecessary indexes:

  • They slow down writes (INSERT, UPDATE, DELETE)
  • They take up disk space
  • Each index consumes memory

Collection statistics

To see statistics for a collection:

db.unicorns.stats()

You will see information about:

  • Number of documents
  • Size of the data
  • Size of the indexes
Activity 1
  1. Create an index on the neighbourhood_group_cleansed field
  2. Create an index on the room_type field
  3. Use explain() to see whether your query uses indexes: db.listings.find({ neighbourhood_group_cleansed: "CIUTAT VELLA" })
  4. Remove the index on neighbourhood_group_cleansed
  5. Run explain again on the same query. Do you see the difference in the winningPlan field?

Pro:

  1. Create a compound index on neighbourhood_group_cleansed and room_type. Verify with explain() that it is used when searching by both fields
  2. Create an index on listing_id in the reviews collection. Verify with explain() that it now uses an index (IXSCAN) instead of a full scan (COLLSCAN)
  3. List all the indexes of the listings collection using getIndexes(). How many indexes are there in total?

Solutions

Building SPAs with Django and HTML Over the Wire: Learn to build real-time single page applications with Python

Building SPAs with Django and HTML Over the Wire: Learn to build real-time single page applications with Python

The HTML over WebSockets approach simplifies single-page application (SPA) development and lets you bypass learning a JavaScript rendering framework such as React, Vue, or Angular, moving the logic to Python. This web application development book provides you with all the Django tools you need to simplify your developments with real-time results.

Buy the book

Help me keep writing

Every coffee gives me a push toward the next article.

Comments

There are no comments yet.