Performance of individual findOne query is abnormally slow (upwards of 60-85ms). Is there something fundamentally wrong with the design below? What steps should I take to make this operation faster?
Goal (fast count of items within a range, under 10-20ms):
- Input max and min time
- Query database for document with closest time for max and min
- Return the "number" field of both query result
- Take the difference of the "number" field to get document count
Setup
MongoDB database
3000 documents, compound ascending index on time_axis, latency_axis, number field
[ { time_axis:1397888153982,latency_axis:5679,number:1},
{ time_axis:1397888156339,latency_axis:89 ,number:2},
...
{ time_axis:1398036817121,latency_axis:122407,number:2999},
{ time_axis:1398036817122,latency_axis:7149560,number:3000} ]
NodeJs
exports.getCount = function (uri, collection_name, min, max, callback) {
var low, high;
var start = now();
MongoClient.connect(uri, function(err, db) {
if(err) {
return callback(err, null);
}
var collection = db.collection(collection_name);
async.parallel([
function findLow(callback){
var query = {time_axis : { $gte : min}};
var projection = { _id: 0, number: 1};
collection.findOne( query, projection, function(err, result) {
low = result.number;
console.log("min query time: "+(now()-start));
callback();
});
},
function findHigh(callback){
var query = {time_axis : { $gte : max}};
var projection = { _id: 0, number: 1};
collection.findOne( query, projection, function(err, result) {
high = result.number;
console.log("max query time: "+(now()-start));
callback();
});
}
],
function calculateCount ( err ){
var count = high - low;
db.close();
console.log("total query time: "+(now()-start));
callback(null, count);
});
});
}
Note: Thank you for Adio for the answer. It turns out mongodb connection only need to be initialized once and handles connection pooling automatically. :)