PostgreSQL是否会短路其BOOL_OR()评估?

时间:2016-09-26 06:02:18

标签: sql postgresql exists boolean-logic boolean-expression

router.get('/generate',function (req, res) { res.set('Content-Disposition', 'attachment; filename=this.txt') res.download(__dirname + '\\this.txt') }); EXISTS快,因为它可以短路

很多时候,我喜欢检查SQL中是否存在某些东西。例如,我这样做:

COUNT(*)

在大多数数据库中,-- PostgreSQL syntax, SQL standard syntax: SELECT EXISTS (SELECT .. FROM some_table WHERE some_boolean_expression) -- Oracle syntax SELECT CASE WHEN EXISTS (SELECT .. FROM some_table WHERE some_boolean_expression) THEN 1 ELSE 0 END FROM dual 被“短路”,即一旦找到一行,数据库就可以停止在表中查找行。 This is usually much faster than comparing COUNT(*) >= 1 as can be seen in this blog post

EXISTSEXISTS

一起使用

有时,我想在GROUP BY查询中为每个组执行此操作,即我想“聚合”存在值。没有GROUP BY聚合函数,但PostgreSQL幸运地支持BOOL_OR()聚合函数,如下所示:

EXISTS

The documentation mentions something about COUNT(*) being slow因为计算计数需要明显的顺序扫描。但不幸的是,它没有说明SELECT something, bool_or (some_boolean_expression) FROM some_table GROUP BY something 被短路的任何内容。是这样的吗? BOOL_OR()遇到第一个BOOL_OR()值时是否会停止汇总新值?

1 个答案:

答案 0 :(得分:1)

如果您想检查是否存在,我通常会使用LIMIT / FETCH FIRST 1 ROW ONLY查询:

SELECT .. FROM some_table WHERE some_boolean_expression
FETCH FIRST 1 ROW ONLY

这通常会在第一次点击后停止执行。

对于另一个表中的每一行(组),可以使用LATERAL应用相同的技术。

SELECT * 
  FROM (SELECT something
          FROM some_table
         GROUP BY something
       ) t1
  LEFT JOIN LATERAL (SELECT ...
                        FROM ...
                       WHERE ...
                       FETCH FIRST 1 ROW ONLY) t2
    ON (true)

t2中,您可以使用与该组的任何行匹配的WHERE子句。它每个组只执行一次,并在找到第一个命中后立即中止。但是,当然,这表现得更好还是更差取决于您的搜索谓词和索引。