【问题标题】:IF EXISTS in T-SQL如果在 T-SQL 中存在
【发布时间】:2011-11-11 18:20:47
【问题描述】:

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

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

return 1

else

return 0

如果表中存在名称 = John 的行,它是停止执行并返回 1,还是遍历整个表以寻找更多匹配项?

【问题讨论】:

  • 仅供参考,您也可以考虑使用 SELECT 1 而不是 SELECT * 以便更好地利用索引(而不是从表中检索所有字段)。
  • @sfuqua This is a myth
  • IF EXISTS (SELECT 1 / 0 FROM table1 WHERE Name='John') ... 这不会出错... SQL 永远不会评估 SELECT... 它只是在查看WHERE.
  • 我使用“SELECT 1”有两个原因。第一,解析器实际上查询表元数据以扩展“*”,直到 SQL 2008,导致小的(可忽略的)性能命中。更重要的原因是直接在代码中交流,列列表没有意义。
  • @codekaizen - 解析器也为SELECT 1 执行此操作,如图所示,由于列权限here 显示“SELECT 1”失败。

标签: sql-server tsql exists


【解决方案1】:

是的,它会停止执行,因此这通常比 HAVING COUNT(*) > 0 更可取,而 HAVING COUNT(*) > 0 通常不会。

对于EXISTS,如果查看执行计划,您会发现table1 的实际行数不会超过1,而与匹配记录的数量无关。

在某些情况下,SQL Server 可以在简化阶段将COUNT 查询的树转换为与EXISTS 相同的树(使用半联接且看不到聚合运算符)an example of that is discussed in the comments here

对于比问题中显示的更复杂的子树,您可能偶尔会发现COUNT 的性能优于EXISTS。因为半连接只需要从子树中检索一行,这可以鼓励对树的该部分使用嵌套循环的计划——这在实践中可能不是最优的。

【讨论】:

  • 是否有更好的方法来执行以下操作: 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我在存储过程中有这个,并且存储过程经常被执行。我的主要动机是提高性能。我知道我可以在 SELECT 中使用常量 1 或 0 而不是 * 但相应的性能提升可以忽略不计
  • @Sidd - 可能取决于确切的查询是什么以及您拥有的索引。你可以改为 SELECT TOP 1 * FROM t1 WHERE xxx ORDER BY some_condition_that_would_mean_yyyy_would_be_first 然后检查结果。
【解决方案2】:

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

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

【讨论】:

  • 不能在此上下文中使用带有返回值的 RETURN 语句。
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 2011-02-18
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多