gpt4 book ai didi

node.js - mongoose/mongodb 流与数组性能

转载 作者:太空宇宙 更新时间:2023-11-04 02:31:21 24 4
gpt4 key购买 nike

在使用 Mongoose、Express 和 JSONStream(如果适用)从 MongoDB 发送文档集合时,我看到了一些意外的性能数据。我想比较 Mongoose 查找和流。我原以为流对于较大的文档集合会更快,但惊讶地发现 toArray 变体始终优于它们。我认为通配符可能是我使用 JSONStream 将响应传送到 Express 的。我的简单端点如下:

// 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));
});
});

更新 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"
}

最佳答案

从 mongo shell 中查看 db.mycollection.stats() 和 db.mycollection.find({}).explain() 的输出会很有帮助。

考虑到您所看到的性能数据,可能只是因为对于足够大的集合,非索引查询的冷 btree 命中才是所有时间都花在的地方,而不是 Node 本身的任何开销。

关于node.js - mongoose/mongodb 流与数组性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26447533/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com