Not all slow MongoDB queries are bad queries.
Sometimes the query is fine, but MongoDB does not have a good index to help with your filtering, sorting, and retrieving of the data
In this tutorial, we'll use payments as an example of our database. The collection starts without a useful index for our query. We'll identify the slow operation, learn about the recommended index, explain why the compound index works, and manage it visually in VisuaLeaf.
The workflow is simple:
slow query -> query profiler -> index recommendation -> compound index -> index manager
You can use the same workflow when your own MongoDB collections start to feel slow.
On this page
- The Slow Query Problem
- The Payments Query We Want to Optimize
- Find the Slow Query in VisuaLeaf
- Read the Index Recommendation
- Why This Compound Index Works
- Check and Manage Indexes
- Indexing Mistakes to Avoid
- FAQ
The Slow Query Problem
MongoDB can return results quickly when a collection is small.
But as the collection grows, the same query can become slower. MongoDB may need to scan many documents, sort a large result set, or check fields that are not indexed.
That extra work is the real problem.
For example, this query looks simple:
db.payments.find({
status: "paid"
})
If the status field has no useful index; MongoDB may scan the collection to find matching documents.
This is called a collection scan.
A collection scan is not always bad. On a tiny collection, it may not matter. On a large collection used by your app every day, it matters a lot.
When you inspect a query plan, these stages are important:
A common warning sign looks like this:
| Stage | Meaning |
|---|---|
COLLSCAN |
MongoDB scanned the collection |
IXSCAN |
MongoDB used an index |
FETCH |
MongoDB fetched documents after using an index |
SORT |
MongoDB performed a sort operation |
totalDocsExamined: 50000
nReturned: 25
That means MongoDB checked 50,000 documents to return only 25.
The goal is not just to make the query look cleaner. The goal is to make MongoDB do less work.
MongoDB explains the technical index behavior in the official MongoDB Indexes documentation.
The Payments Query We Want to Optimize
Now letβs use a more realistic query.
Imagine you have a payments collection, and you often need to find *'paid'* USD payments above a certain amount, sorted by the newest payment date.
The query looks like this:
db.payments.find({
currency: "USD",
status: "paid",
amount: { $gte: 100 }
}).sort({
paidAt: -1
})
This query does four things:
If your payments collection has no useful index for this pattern, MongoDB has to work harder than necessary.
| Field | What the query does |
|---|---|
currency |
Keeps only payments in USD |
status |
Keeps only paid payments |
amount |
Keeps payments greater than or equal to 100 |
paidAt |
Sorts newest payments first |
A single-field index can help with simple filters, but this query uses multiple fields.
That is why a compound index makes more sense here. It can support the filter, sort, and range condition together.
We will let VisuaLeaf recommend the exact index after we inspect the slow query.
MongoDB documents compound indexes in the official Compound Indexes documentation.
Find the Slow Query in VisuaLeaf
Do not create indexes because a field looks important.
Find the slow query first. Then index the query pattern.
Use the same payments query from the previous section in the Visual Query Builder. Add the filters for currency, status, and amount, then sort by paidAt descending.
In VisuaLeaf, the Explain view shows the execution plan, scanned documents, returned documents, execution time, and index usage.
If MongoDB scans many documents and returns only a few, the query probably needs a better index.
You can also run the same check manually with explain():
db.payments.find({
currency: "USD",
status: "paid",
amount: { $gte: 100 }
}).sort({
paidAt: -1
}).explain("executionStats")
When you read the result, check these values:
| Metric | What you check |
|---|---|
totalDocsExamined |
How many documents MongoDB scanned |
nReturned |
How many documents MongoDB returned |
executionTimeMillis |
How long the query took |
winningPlan |
Which execution plan MongoDB selected |
Look for IXSCAN when MongoDB uses an index, and COLLSCAN when MongoDB scans the collection. For one query, the Explain view is enough.
For repeated slow operations across collections, use VisuaLeaf Query Profiling. The profiler helps you see slow operations over time, not just one query you are testing manually.
MongoDB also provides database profiling features for slow operations. You can read more in the official Database Profiler documentation.
Read the Index Recommendation
After you find the slow query, check which index would actually help.
In this example, the payments collection has no useful index for the query. VisuaLeaf detects repeated collection scans and recommends a compound index based on the fields used by the query.
The recommendation for the compound index is:
db.payments.createIndex({
currency: 1,
status: 1,
paidAt: -1,
amount: 1
})
This is useful because the recommendation does not only say βadd an index.β
It shows the exact fields and the order.
That order is the important part.
Why This Compound Index Works
The recommended index matches the way the query filters and sorts the data.
After creating the recommended index, run the same query again in the Explain view.
After creating the compound index, VisuaLeaf shows that MongoDB uses the index for the payments query.
Now MongoDB uses the compound index instead of scanning the full collection.
The query first filters by currency and status, then sorts by paidAt, and also applies a range condition on amount.
In simple terms:
| Field | Why it is in the index |
|---|---|
currency |
Exact filter |
status |
Exact filter |
paidAt |
Sort by newest payment |
amount |
Range condition |
Check and Manage Indexes
After you create an index, check what exists in the collection.
Indexes are easy to add and easy to forget.
Over time, a collection can collect old indexes, duplicate indexes, or indexes created for queries that no longer exist.
Use the Index Manager to review the indexes on your collection.
The Index Manager helps you check the index name, fields, type, size, usage, properties, and status.
This helps you avoid creating the same index twice.
It also helps you review old indexes when your application queries change.
You can combine this workflow with the Visual Query Builder, MongoDB Shell, Aggregation Pipeline Builder, and Charts and Dashboards when you need to test, analyze, and present your MongoDB data.
If you prefer, you can create the index visually from the Index Manager instead of writing the command manually.
Indexing Mistakes to Avoid
Indexes help when they match your workload.
They create problems when you add them without a reason.
Creating indexes for every field
Do not index every field in the collection.
Each index needs storage. Each index also adds work when MongoDB inserts, updates, or deletes documents.
Create indexes for queries your application actually runs.
Ignoring the sort
A query may filter quickly but still sort slowly.
Example:
db.payments.find({
status: "paid"
}).sort({
paidAt: -1
})
A useful index is:
db.payments.createIndex({
status: 1,
paidAt: -1
})
This supports the filter and the sort.
Putting fields in the wrong order
A compound index is not only about choosing the right fields. The order matters too.
For the payments query, starting with the *amount* is not as useful as starting with the *currency* and *status, because the *amount** is a range condition.
Same fields. Different order. Different performance.
Keeping indexes you no longer use
Your application changes.
Your queries change.
Your indexes should change too.
Review unused indexes from time to time and remove the ones that no longer support real queries.
Conclusion
MongoDB query optimization starts with the query pattern.
Do not guess. Find the slow query first. Check whether MongoDB scans too many documents. Then create an index that matches how your query filters, sorts, and ranges over the data.
For simple filters, a single field index may be enough.
For queries like the payments example, a compound index is usually better.
With VisuaLeaf, you can detect slow queries, review index recommendations, and manage MongoDB indexes visually in one place.








Top comments (0)