How to get an explain for a MongoDB count?
Mongo 3.0 introduced a new way of explaining non-cursor requests:
db.my_collection.explain().count()
See: http://docs.mongodb.org/manual/reference/method/db.collection.explain/#db.collection.explain
Based on https://jira.mongodb.org/browse/SERVER-14098, a new future version will support this in the format:
db.runCommand({ explain: { count: 'collectionName', query: { foo: 'bar' } }})
I'm pretty sure that count(query) is short for find(query).count()--in other words, the explain is exactly the same. There's no specific counting optimization done, except maybe for a full collection count. For example, running a count on a non-indexed field for a range takes exactly the same amount of time as running a find.explain with the same range.
I wrote a function called timeCount that takes the average of the count function time, and then shows the explain output for comparison.
function timeCount(coll, query) { var n = 5; var total = 0; for(var i = 0; i < n; i++) { var start = new Date(); db[coll].find(query).count(); var end = new Date(); total += (end - start); print("time[" + i + "]: " + (end - start) + "ms"); } print("average time: " + (total / n)); var explain = db[coll].find(query).explain(); print("explain (from find): "); for(e in explain) { if(typeof explain[e] == "string" || typeof explain[e] == "number") { print(e + ": " + explain[e]); } }}
The output looks like this:
> timeCount('test',{x:{$gt:5000}});time[0]: 1339mstime[1]: 1280mstime[2]: 1347mstime[3]: 1322mstime[4]: 1299msaverage time: 1317.4explain (from find): cursor: BtreeCursor x_1_y_1nscanned: 995062nscannedObjects: 995062n: 995062millis: 1390nYields: 0nChunkSkips: 0