如果存在于 T-SQL 中的用法

53

如果我们在 IF EXISTS 中有一个 SELECT 语句,那么执行会在找到表中的一条记录后立即停止吗?例如:

IF EXISTS(SELECT *  FROM  table1  WHERE Name='John' )

return 1

else

return 0

如果表中存在一个名字为 John 的行,它会停止执行并返回 1 吗?还是会遍历整个表查找更多匹配项?


你可能想考虑使用SELECT 1而不是SELECT *,这样可以更好地利用索引(不检索表中的所有字段)。 - sfuqua
18
这是一个谬论。 - Martin Smith
3
如果存在(选择1/0从table1中,其中Name='John'),那么这不会出错。SQL不会评估“SELECT”,它只是查看“WHERE”。 - Timothy Khouri
3
我使用“SELECT 1”有两个原因。首先,解析器实际上会查询表元数据以扩展“*”,最近在SQL 2008中导致了一些(可以忽略的)性能损失。更重要的原因是直接在代码中传达列列表是无意义的。 - codekaizen
2
@codekaizen - 解析器也会对SELECT 1执行此操作,因为这里的图表和示例显示了由于列权限而失败的"SELECT 1" 链接 - Martin Smith
2个回答

54

是的,它会停止执行,因此通常比 HAVING COUNT(*) > 0 更可取,后者经常不起作用。

使用 EXISTS,如果查看执行计划,会发现从 table1 中输出的实际行数不会超过1,无论匹配记录的数量如何。

在某些情况下,SQL Server 可以在简化阶段将 COUNT 查询的树转换为与 EXISTS 相同的树(使用半连接并且没有聚合运算符),这里的评论中讨论了一个例子

对于比问题中显示的更复杂的子树,偶尔可能会发现 COUNTEXISTS 执行得更好。因为半连接只需要从子树中检索一行,所以这可能会鼓励使用嵌套循环的计划,但在实践中可能不是最优选择。


1
有没有更好的方法来执行以下操作: IF EXISTS(SELECT * FROM t1 WHERE xxx AND yyy) RETURN 2 ELSE BEGIN IF EXISTS(SELECT * FROM t1 WHERE xxx) RETURN 1 ELSE RETURN 0 END 我将其放在存储过程中,该存储过程经常被执行。我的主要动机是提高性能。我知道可以使用常量1或0而不是SELECT中的*,但相应的性能改进微不足道。 - Sidd
@Sidd - 可能取决于确切的查询和您拥有的索引。您可以改为执行 SELECT TOP 1 * FROM t1 WHERE xxx ORDER BY some_condition_that_would_mean_yyyy_would_be_first,然后检查结果。 - Martin Smith

-5

在这种情况下不需要使用“else”:

IF EXISTS(SELECT *  FROM  table1  WHERE Name='John' ) return 1
return 0

在此上下文中不能使用带有返回值的RETURN语句。 - Aditya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接