SELECT * 从具有 50k 条记录的简单 table 开始似乎需要 40 秒

SELECT * from simple table with 50k records seems to take 40 seconds

这是我的 table:

CREATE TABLE public.logs (
  logid bigint NOT NULL DEFAULT nextval('applog_logid_seq'::regclass),
  applicationname character varying(50),
  loglevel character varying(10),
  logmessage character varying(500),
  stacktrace character varying(4096),
  occurredon timestamp without time zone,
  loggedon timestamp without time zone,
  username character varying(50),
  groupname character varying(50),
  useragent character varying(512),
  CONSTRAINT applog_pkey PRIMARY KEY (logid)
);

当我在 运行 SELECT *... 上时,在我的本地机器上 return 50000 行需要 40 秒。我在 SQL 服务器的本地安装上有相同的 table,不到一秒钟就可以 return 获得相同数量的数据。

我正在为我们的新堆栈评估 PostgreSQL,这让我非常担心。为什么我做 wrong/why 是 PostgreSQL 这么慢?

编辑:

这是我从 EXPLAIN (BUFFERS, ANALYZE, TIMING OFF) SELECT * FROM public.logs 得到的:

所以看起来服务器将在大约 6 毫秒内执行此操作。我想这意味着所有的开销都在 pgAdmin III 中,但是 SSMS 是如何做到这么快的呢?

非常感谢大家把我从悬崖上拉下来的帮助:)

我编写了一个节点控制台应用程序,消除了我的顾虑。事实上,我的 Postres 实例比 SQL 服务器快了大约 50%(正如@Guillaume F. 指出的那样)。在同一个客户端中,结果如下:

Postres (RDS) query duration: 7062ms

Postres (RDS) rows returned: 50000

Postgres (Local) query duration: 1919ms

Postgres (Local) rows returned: 46154

MSSQL (local) query duration: 4681ms

MSSQL (local) rows returned: 50000

如果有人有兴趣在自己的环境中复制我的结果,请查看示例应用程序:

'use strict';

let pgp = require('pg-promise')();
let db = pgp("postgres://username:password@server:5432/db");
let localdb = pgp("postgres://username:password@server:5432/db");
var mssql = require('mssql');

let start = new Date();
db.query('select * from logs').then((result) => {
    console.log("Postres (RDS) query duration: " + (new Date() - start) + "ms");
    console.log("Postres (RDS) rows returned: " + result.length);
    console.log("");

    let localstart = new Date();
    localdb.query('select * from logs').then((localresult) => {
        console.log("Postgres (Local) query duration: " + (new Date() - localstart) + "ms");
        console.log("Postgres (Local) rows returned: " + localresult.length);
        console.log("");

        var config = {
            user: 'username',
            password: 'password',
            server: 'server', // You can use 'localhost\instance' to connect to named instance 
            database: 'db'
        };

        mssql.connect(config).then(function () {

            // Query 
            let localMSSqlStart = new Date();
            new mssql.Request().query('select TOP 50000 * from dbo.AppLog ORDER BY 1 DESC').then(function (recordset) {
                console.log("MSSQL (local) query duration: " + (new Date() - localMSSqlStart) + "ms");
                console.log("MSSQL (local) rows returned: " + result.length);
                console.log("");
            }).catch(function (err) {

                // ... query error checks
                console.log("Problem querying MSSQL: " + err);
            });
        }).catch(function (err) {

            // ... connect error checks 
            console.log("Problem connecting to MSSQL: " + err);
        });
    });
});

编辑:(作者 pg-promise

附带说明一下,这只是为了展示如何以更文明的方式对 PostgreSQL 进行基准测试:

let pgp = require('pg-promise')();
let db = pgp("postgres://username:password@server:5432/db");
let localdb = pgp("postgres://username:password@server:5432/db");

db.result('select * from logs')
    .then(r => {
        console.log("Postres (RDS) rows returned:", r.rows.length);
        console.log("Postres (RDS) query duration:", r.duration + 'ms\n');
        return localdb.result('select * from logs')
            .then(r => {
                console.log("Postgres (Local) rows returned:", r.rows.length);
                console.log("Postgres (Local) query duration:", r.duration + 'ms\n');
            })
    })
    .catch(error=> {
        console.log(error);
    });

使用方法 result 进行基准测试的优点是 pg-promise 自动将 Result 扩展为 属性 duration.

正如我们所怀疑的那样,正如我们从 EXPLAIN 输出中看到的那样,几乎 none 的时间花在了服务器上,但用于传输(网络延迟)和渲染输出。我们在您添加到问题的 EXPLAIN 输出中看到 7 毫秒。

在 pgAdmin III 中呈现大量文本不是很快。两个提示:

  1. 大多数时候,您不需要查看巨大栏目中的所有内容。为了加快速度,您可以在 pgAdmin III 中设置最大显示字符数。但是,如果您只看到长字符串的前导片段,请不要感到困惑:

  2. pgAdmin 4 beta 2 已发布 (2016-6-24)。尚未发布,但由于它是完全重写的,因此性能可能会有很大不同。 More on project's site.