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.
使用带有GROUP BY的EXISTS
有时,我想在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()被短路了.是这样的吗?一旦遇到第一个TRUE值,BOOL_OR()是否会停止聚合新值?
解决方法
如果你想检查是否存在,我通常使用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子句.它每个组只执行一次,并在找到第一个命中后立即中止.但是,当然,这表现得更好还是更差取决于您的搜索谓词和索引.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。