nodejs + postgresql方式太慢了

时间:2014-10-01 01:51:27

标签: node.js postgresql

我有这段代码:

var pg = require('pg');
var QueryStream = require('pg-query-stream');
var constr = 'postgres://devel:1234@127.0.0.1/tcc';
var JSONStream = require('JSONStream');
var http = require('http');

pg.connect(constr, function(err, client, done) {
    if (err) {
        console.log('Erro ao conectar cliente.', err);
        process.exit(1);
    }

    sql = 'SELECT \
          pessoa.cod, \
          pessoa.nome, \
          pessoa.nasc, \
          cidade.nome AS cidade \
          FROM pessoa, cidade \
          WHERE cidade.cod IN (1, 2, 3);';

    http.createServer(function (req, resp) {
        resp.writeHead(200, { 'Content-Type': 'text/html; Charset=UTF-8' });
        var query = new QueryStream(sql);
        var stream = client.query(query);

        //stream.on('data', console.log);
        stream.on('end', function() {
            //done();
            resp.end()
        });
        stream.pipe(JSONStream.stringify()).pipe(resp);
    }).listen(8080, 'localhost');
});

当我在它上面运行apache bench时,它每秒只能获得大约四个请求。 如果我在php / apache或java / tomcat中运行相同的查询,我会快十倍 结果。该数据库有1000行。如果我将查询限制为大约十行, 然后节点比php / java快两倍。

我做错了什么?

编辑:前段时间我在这里开了一个问题:https://github.com/brianc/node-postgres/issues/653

我提供此链接是因为我在我尝试过的代码上发布了其他一些变体。 即使有目前的评论和提示,我也无法获得下降速度。

4 个答案:

答案 0 :(得分:4)

  • pg-query-stream使用游标。
  • 它使用游标(粗体强调)。
  • 您可以阅读代码并更改batchSize以更好地满足您的需求。

对于那些不知道游标是什么的人来说,简而言之,他们是保持内存占用空间小而不是在内存中读取整个表格的权衡。但是,如果您在获得100结果时获得1000行,那么1000 / 100次往返;所以可能比不使用游标的解决方案慢10x

如果您知道需要多少行,请在查询中添加limit,并更改每次返回的行数,以最大限度地减少往返次数。

答案 1 :(得分:1)

据我从这段代码中可以看出,你创建了一个与PostgreSQL的单一连接,所有内容都排在队列中。

pg模块允许这样做,它在这里描述: https://github.com/brianc/node-postgres/wiki/Queryqueue

如果你想要一个真正的性能,你应该从每个HTTP请求中获取池中的连接,使用它,释放它并使101%确保你总是释放(例如正确的异常处理)或者你的服务器将死掉一次游泳池完全耗尽。

在那里,您可以调整连接池参数并测量性能。

答案 2 :(得分:0)

看起来您在请求被转发之前等待创建服务器。尝试在调用之外移动http.createServer。如果您只想在请求中使用http服务器,则应尝试将调用设置为异步。

答案 3 :(得分:0)

也许你应该设置http.agent.maxSockets值,试试这个:

var http = require('http');
http.agent.maxSockets = {{number}};

默认maxSockets为5