首页 文章

PSQL比PgAdmin III慢

提问于
浏览
4

我一直在分析我的应用程序的一些部分,并且我发现PgAdmin3在执行完全相同的脚本时比psql快得多 . 我正在使用unix套接字,Ubuntu 12.04和Postgresql 9.1以及pgadmin3 v1.14 . 我有一个简单的脚本,如下所示:

BEGIN
INSERT INTO key_value(section,key,value) VALUES('section','key1','value');
....
INSERT INTO key_value(section,key,value) VALUES('section','key10000','value');
COMMIT;

这是表格:

CREATE TABLE key_value
(
  key text NOT NULL,
  value text,
  CONSTRAINT key_value_pkey PRIMARY KEY (section , key )
)
WITH (
  OIDS=FALSE
);

此脚本中有10000个插入 . 在pgadmin3中执行它需要大约0.5秒,在psql中执行它需要2.5~3.5秒 . 两者都包含在一个事务中,所以应该没有什么区别 . 在重新创建表,完全真空等结果是一致的 . 登录Postgresql服务器显示postgres在psql中执行时为每个insert语句执行日志,但在从pgadmin3执行时只有一个日志 .

psql执行完成以下操作:

psql  -n -t -f p.sql -o/dev/null

并且还测试了

psql  -n -t -1 -f p.sql -o/dev/null

我的问题是为什么psql这么慢以及为什么我们postgresql在一个客户端中记录每个语句但在另一个客户端只记录整个事务,而且有一个简单的修复psql .

EDIT 只是为了澄清,我记录的持续时间不是声明:

在服务器中,当使用psql执行时,我得到以下内容

2012-10-02 12:20:32 CEST LOG:  duration: 0.283 ms
....
2012-10-02 12:20:35 CEST LOG:  duration: 0.285 ms
2012-10-02 12:20:35 CEST LOG:  duration: 0.291 ms
2012-10-02 12:20:35 CEST LOG:  duration: 0.279 ms
2012-10-02 12:20:35 CEST LOG:  duration: 0.284 ms
2012-10-02 12:20:35 CEST LOG:  duration: 0.279 ms
2012-10-02 12:20:35 CEST LOG:  duration: 0.299 ms
....
2012-10-02 12:20:36 CEST LOG:  duration: 5.779 ms

使用pgadmin3执行时:

2012-10-02 12:23:21 CEST LOG:  duration: 532.695 ms

psql和pgadmin3中的用户和数据库是相同的

2 回答

  • 1

    我的提示:pgAdmin将脚本作为一个多语句执行 - 因此网络(协议)开销较少 .

  • 3

    psql 有一个集成的解析器,它将分号识别为语句分隔符 . 它使用它将SQL脚本分解为多个语句,与pgadmin相反,如Pavel's answer中所述 .

    没有选项可以关闭此行为 . 但是,使用DO匿名代码块应该可以获得类似的结果而几乎没有变化 . 如果你写这样的脚本:

    DO $$
    BEGIN
    INSERT INTO key_value(section,key,value) VALUES('section','key1','value');
    ....
    INSERT INTO key_value(section,key,value) VALUES('section','key10000','value');
    END $$;
    

    这将像pgadmin一样发送到服务器(虽然它在技术上完全不同),并且可能在相当的时间内执行 .

    编辑:根据@vseguip评论,这是不高效的,因为plpgsql解释器花费在这些10k语句上的时间 .

    替代IDEA:将脚本更改为只有一个具有多行的INSERT,而不是多个INSERT,没有DO块 .

    BEGIN;
    INSERT INTO key_value(section,key,value) VALUES('section','key1','value'),
          ('section','key2','value'),
          ('section','key3','value'),
          ....
          ('section','key10000','value');
    END;
    

相关问题