Indexesmedium3-5 years

An index exists as `{ status: 1, total: 1, placedAt: -1 }`, built for a query filtering on `status` and `total` and sorting by `placedAt`. The query is still slow and `explain()` shows a `SORT` stage. What's wrong with the index's field order, and how do you fix it?

A compound index only serves a sort without an extra in-memory sort when its fields follow Equality, Sort, Range — in that order. Here the range field (total) sits before the sort field (placedAt), so within a fixed status value the index is ordered by total first and placedAt only within each total value — there's no single run of the index that's already ordered by placedAt across every matching document. MongoDB has to gather every document matching the status and total conditions, then sort them all by placedAt in memory, which is exactly the SORT stage in the plan. The fix is to reorder the index to { status: 1, placedAt: -1, total: 1 } — equality first, then the sort field, then the range — so the index itself is already in the order the query needs and total becomes a per-document filter check during the scan instead of a field the index is organised by.

The lesson behind it →
More on Indexes