EXISTS
比 COUNT(*)
快,因为它可以短路
很多时候,我喜欢在 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 .
使用 EXISTS
和 GROUP 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/