Last friday I attended a 10Gen event here in São Paulo, it was an awesome event where I've learned lots of new things about MongoDB.
One of the things the caught my attention was the way MongoDB generates its query plans.
Unlike most databases where query plan generation is arbitrarily based on its cost probability, statistics and some pre-defined rules, MongoDB just runs multiple different query plans in parallel, comparing their results and selecting the best one, based on its nscanned results number.
nscanned
Whenever a query rans, MongoDB scans N documents until it finds the query results.
You can check this running a query explain on any query:
> db.accounts.find({status: 'deleted'}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 484,
"nscannedObjects" : 484,
"n" : 3,
"millis" : 56,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
}
}
Whichever query has the smallest nscanned number is the chosen the fastest query and its query plan gets cached.
Updating the query plan
Every time a query rans a 1000 or so times, MongoDB checks to see if the selected query plan still is the best one.
This verification also happens if something changes on the collection, like adding an index, or if the result of any query has a nscanned number 10 times bigger than the cached one.
You can learn more about query plans on the MongoDB official documentation.