Я вижу некоторые неожиданные номера производительности, когда дело доходит до отправки коллекции документов из MongoDB с использованием Mongoose, Express и JSONStream, когда это применимо. Я хотел сравнить поиск мангуста против потока. Я ожидал, что поток будет быстрее для больших коллекций документов, но был удивлен, увидев, что варианты toArray превосходят их последовательно. Я думаю, что подстановочный знак может быть моим использованием JSONStream, чтобы передать ответ, чтобы выразить. Мои простые конечные точки ниже:mongooose/mongodb streams vs array performance
// run this after connecting to mongoose
var app = express();
var myModel = ...; // get mongoose model
var myCollection = myModel.collection;
// fetch 500 - use lean w/ mongoose
var queryOpts = { lean : true, limit : 500 };
// 35.958
app.get("/api/v1/stream", function(req, res) {
res.set('Content-Type', 'application/json');
myModel.find({ }, null, queryOpts)
.stream().pipe(JSONStream.stringify()).pipe(res);
});
// 36.228
app.get("/api/v1/mongostream", function(req, res) {
res.set('Content-Type', 'application/json');
myCollection.find({ }, queryOpts)
.stream().pipe(JSONStream.stringify()).pipe(res);
});
// 23.399ms
app.get("/api/v1/mongoarray", function(req, res) {
myCollection.find({ }, queryOpts)
.toArray(function(err, results) {
res.json(results);
});
});
// 23.908
app.get("/api/v1/array", function(req, res) {
myModel.find({ }, null, queryOpts, function(err, results) {
res.json(results);
});
});
app.listen(4000);
Комментарий над каждой конечной точки указывает среднее время запроса сообщенный ab -k -n 1000 <endpoint>
. Я удивлен, что передача потока курсора в JSONStream для экспресс-ответа примерно на 50% медленнее, чем просто выборка всего и отправка. Я ожидал, что данные будут работать лучше.
Есть ли что-то, что я делаю, это, очевидно, неправильно? Неужели я ошибаюсь, чтобы думать, что потоки должны быть быстрее? Если JSONStream является виновником, то лучший способ перейти от потока курсора к выражению ответа - если я все-таки буду его буферировать, не будет ли это то же самое, что и один из вариантов массива?
Обратите внимание, что сервер БД - это mongo 2.4.x, а драйвер mongo - 1.4.x.
Обновление Я рассчитал только часть выборки/потоковой передачи, а не аспект сериализации. Оба варианта массива и потоковая передача были одинаковыми по времени с небольшим краем к вариантам массива (14,9 мс против 15,3 мс). Ниже приведены конечные точки:
// No serialization - just timing
// all are nearly the same - slight edge to
// arrays
app.get("/api/v2/stream", function(req, res) {
var start = process.hrtime();
res.set('Content-Type', 'application/json');
myModel.find({ }, null, queryOpts)
.stream().on('end', function() {
res.json(process.hrtime(start));
});
});
app.get("/api/v2/mongostream", function(req, res) {
var start = process.hrtime();
res.set('Content-Type', 'application/json');
myCollection.find({ }, queryOpts)
.stream().on('end', function() {
res.json(process.hrtime(start));
});
});
app.get("/api/v2/mongoarray", function(req, res) {
var start = process.hrtime();
myCollection.find({ }, queryOpts)
.toArray(function(err, results) {
res.json(process.hrtime(start));
});
});
app.get("/api/v2/array", function(req, res) {
var start = process.hrtime();
myModel.find({ }, null, queryOpts, function(err, results) {
res.json(process.hrtime(start));
});
});
Update 2 Выход collection.stats()
и collection.find({}).explain()
ниже:
> db.myCollection.stats();
{
"ns" : "myDb.myCollection",
"count" : 1000,
"size" : 419264,
"avgObjSize" : 419.264,
"storageSize" : 847872,
"numExtents" : 4,
"nindexes" : 2,
"lastExtentSize" : 655360,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 98112,
"indexSizes" : {
"_id_" : 40880,
"_meta.tags_1" : 57232
},
"ok" : 1
}
> db.myCollection.find({}).explain();
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 1000,
"nscannedObjects" : 1000,
"nscanned" : 1000,
"nscannedObjectsAllPlans" : 1000,
"nscannedAllPlans" : 1000,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
},
"server" : "LOCAL:27017"
}
Таким образом, в любом случае это 1000 объектов или около 400 тыс. Данных, что является своего рода территорией шума для Монго. С 100 миллионами объектов в коллекции поток курсора становится интересным; с тем, что у вас есть сейчас, либо запрос будет быстрым, вероятно, неразличимым. –