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

标签 sql postgresql exists boolean-logic boolean-expression

EXISTSCOUNT(*) 快,因为它可以短路

很多时候,我喜欢在 SQL 中检查事物是否存在。例如,我这样做:

-- 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

在大多数数据库中,EXISTS 是“短路”的,即数据库可以在找到一行后立即停止在表中查找行。 This is usually much faster than comparing COUNT(*) >= 1 as can be seen in this blog post .

使用 EXISTSGROUP BY

有时,我想在 GROUP BY 查询中为每个组执行此操作,即我想“聚合”存在值。没有 EXISTS 聚合函数,但幸运的是 PostgreSQL 支持 BOOL_OR()聚合函数,就像在这个语句中:

SELECT something, bool_or (some_boolean_expression)
FROM some_table
GROUP BY something

The documentation mentions something about COUNT(*) being slow因为计算计数需要明显的顺序扫描。但不幸的是,它没有说明 BOOL_OR() 被短路的情况。是这样吗? BOOL_OR() 是否会在遇到第一个 TRUE 值时立即停止聚合新值?

最佳答案

如果您想检查是否存在,我通常使用 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 子句来匹配组的任何行。它每组只执行一次,并在发现第一个命中时立即中止。但是,这当然是好是坏取决于您的搜索谓词和索引。

关于sql - PostgreSQL 是否会短路其 BOOL_OR() 评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39695647/

相关文章:

mysql - 列别名不适用于 MySQL 中的 Group、Where 和 Having

sql - POSTGRESQL 必须出现在 GROUP BY

database - 使用远程 PostgreSQL 数据库的 Jenkins 用户登录

python - Ubuntu 14.04 + liblwgeom-2.1.1 postgres

c# - ASP.NET C# 不检查数据库中是否存在用户

hadoop - 仅允许使用顶级连词的SubQuery表达式

php - MySQL 地理位置显示错误的距离

php - 从 MySQL 查询中添加

postgresql - 如何使用 uid :gid set correctly 在 openshift 中挂载 secret

python - 如何检查 Python 列表中是否存在元组?