0

需要运行查询以查看至少存在一条记录的位置。所以问题“什么更有效”:

PERFORM * FROM table 

或者

PERFORM 1 FROM table

为什么?

4

2 回答 2

2

需要注意的是,首先,这PERFORM不是一条 SQL 指令,它是一个plpgsql关键字,它指示解释器运行等效的 SELECT,然后丢弃结果。

根据文档(执行没有结果的命令):

执行查询;
这将执行查询并丢弃结果。编写查询的方式与编写 SQL SELECT 命令的方式相同,但将初始关键字 SELECT 替换为 PERFORM。对于 WITH 查询,请使用 PERFORM,然后将查询放在括号中。(在这种情况下,查询只能返回一行。) PL/pgSQL 变量将被替换到查询中,就像不返回结果的命令一样,并且计划以相同的方式被缓存。此外,如果查询产生了至少一行,则特殊变量 FOUND 设置为 true,如果没有产生任何行,则设置为 false

所以问题是一样的:如何SELECT * FROM tableSELECT 1 FROM table比较来检查表中是否至少有一行?但问题是它们在性能方面都不够好,而且如果表有很多行,实际上它们的不足是可笑的。

让我们在最新的 PostgreSQL 9.3 上用两个大表来测试一个真实的例子:

  • words(int,text)(340万行,而且文本栏总是很小)
  • inverted_word_index(int,int,bytea,int)(约 1000 万行,bytea 平均 400 字节宽,最大 2kB)

查询连续重复几次,我只保留 psql 的最快执行\timing on

用第一个表测试 1

PERFORM 1 从单词:

mlists=> do $$ begin perform 1 from words; 结尾; $$;
做
时间:521,379 毫秒

PERFORM * 来自单词:

mlists=> do $$ begin perform * from words; 结尾; $$;
做
时间:442,800 毫秒

结果 1:在这张桌子上,perform *似乎始终比perform 1.

用第二张桌子测试 2

从 reverse_word_index 执行 1:

mlists=> do $$ begin perform 1 from reverse_word_index ; 结尾; $$;
做
时间:2206,230 毫秒

PERFORM * from reverse_word_index:

mlists=> do $$ begin perform * from reverse_word_index ; 结尾; $$;
做
时间:16848,971 毫秒

结果 2:对于这个表,最好的执行perform *比最好的执行慢得多perform 1,所以这与之前的结果相反。

结论:一般来说没有赢家,这似乎取决于表格内容。

但真正有趣的一点是,这两种方法都对表格进行全扫描,而不是在第一行停止,所以它们都太慢了。

相当快速的方法

mlists=> do $$ begin perform 1 from words limit 1; 结尾; $$;
做
时间:0,330 毫秒

mlists=> do $$ begin perform * from words limit 1; 结尾; $$;
做
时间:0,405 毫秒

mlists=> do $$ 从 reverse_word_index 限制 1 开始执行 1;结尾; $$;
做
时间:0,333 毫秒

mlists=> do $$ begin perform * from reverse_word_index limit 1; 结尾; $$;
做
时间:0,314 毫秒

重复执行表明,两种构造的持续时间在 0.3 毫秒和 0.4 毫秒之间变化,没有赢家。它是如此之低,以至于速度差异来自无关的动态因素。

于 2013-10-17T13:32:03.573 回答
0

我不确定您为什么要丢弃结果。

就个人而言,我会使用以下内容:

select count(*)
into   rows_exist
from   (select * from my_table limit 1) t;

保证返回值为 0 或 1 的单行,并且只读取表中的单行以执行此操作。

至于“1”与“*”——我的直觉是说优化器足够聪明,只能读取回答查询所需的列。

但是,如果您使用 (verbose true)运行解释,则表明所有列都是从子查询中投影的。如果是这种情况,那么使用“select *”可能会降低效率,特别是如果从表的开头删除了大量行并且使用“select *”会导致许多块被完整读取在找到第一个之前进行表扫描。我欢迎 PostgreSQL 内部专家的意见,看看这是否是对计划的正确解释。

于 2013-10-17T10:37:28.883 回答