需要运行查询以查看至少存在一条记录的位置。所以问题“什么更有效”:
PERFORM * FROM table
或者
PERFORM 1 FROM table
为什么?
需要运行查询以查看至少存在一条记录的位置。所以问题“什么更有效”:
PERFORM * FROM table
或者
PERFORM 1 FROM table
为什么?
需要注意的是,首先,这PERFORM
不是一条 SQL 指令,它是一个plpgsql
关键字,它指示解释器运行等效的 SELECT,然后丢弃结果。
根据文档(执行没有结果的命令):
执行查询;
这将执行查询并丢弃结果。编写查询的方式与编写 SQL SELECT 命令的方式相同,但将初始关键字 SELECT 替换为 PERFORM。对于 WITH 查询,请使用 PERFORM,然后将查询放在括号中。(在这种情况下,查询只能返回一行。) PL/pgSQL 变量将被替换到查询中,就像不返回结果的命令一样,并且计划以相同的方式被缓存。此外,如果查询产生了至少一行,则特殊变量 FOUND 设置为 true,如果没有产生任何行,则设置为 false
所以问题是一样的:如何SELECT * FROM table
和SELECT 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 毫秒之间变化,没有赢家。它是如此之低,以至于速度差异来自无关的动态因素。
我不确定您为什么要丢弃结果。
就个人而言,我会使用以下内容:
select count(*)
into rows_exist
from (select * from my_table limit 1) t;
保证返回值为 0 或 1 的单行,并且只读取表中的单行以执行此操作。
至于“1”与“*”——我的直觉是说优化器足够聪明,只能读取回答查询所需的列。
但是,如果您使用 (verbose true)运行解释,则表明所有列都是从子查询中投影的。如果是这种情况,那么使用“select *”可能会降低效率,特别是如果从表的开头删除了大量行并且使用“select *”会导致许多块被完整读取在找到第一个之前进行表扫描。我欢迎 PostgreSQL 内部专家的意见,看看这是否是对计划的正确解释。