我看到有些人使用EXISTS (SELECT 1 FROM ...)
而不是EXISTS (SELECT id FROM ...)
作为优化 - 而不是查找并返回值,SQL Server可以简单地返回它给出的文字。
SELECT(1)
总是更快吗?从表中选择一个值是否需要选择文字会避免的工作?
答案 0 :(得分:8)
在SQL Server中,无论您在SELECT 1
中使用SELECT *
还是EXISTS
,都没有区别。您实际上并没有返回行的内容,而是由WHERE
子句确定的集合不是空的。尝试与SET STATISTICS IO ON
并排运行查询,您可以证明这些方法是等效的。我个人更喜欢SELECT *
内的EXISTS
。
答案 1 :(得分:6)
出于谷歌的考虑,我将使用与此问题(Subquery using Exists 1 or Exists *)相同的答案更新此问题,因为(目前)不正确的答案被标记为已接受。注意,SQL标准实际上说通过*的EXISTS与常量相同。
没有。这已被覆盖了数十亿次。 SQL Server是智能的,并且知道它正用于EXISTS,并将NO DATA返回给系统。
Quoth Microsoft: http://technet.microsoft.com/en-us/library/ms189259.aspx?ppud=4
子查询的选择列表 几乎总是由EXISTS介绍 由星号(*)组成。有 没有理由列出列名,因为 你只是测试行是否 符合规定的条件 子查询存在。
另外,不相信我?尝试运行以下内容:
SELECT whatever
FROM yourtable
WHERE EXISTS( SELECT 1/0
FROM someothertable
WHERE a_valid_clause )
如果它实际上是在使用SELECT列表做某事,它会抛出一个div为零的错误。它没有。
编辑:注意,SQL标准实际上是在讨论这个问题。
ANSI SQL 1992 Standard,第191页http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
3) Case: a) If the <select list> "*" is simply contained in a <subquery> that is immediately contained in an <exists predicate>, then the <select list> is equivalent to a <value expression> that is an arbitrary <literal>.
答案 2 :(得分:4)
当您使用SELECT 1时,您清楚地显示(对于以后正在阅读您的代码的人)您测试该记录是否存在。即使没有性能提升(将要讨论),代码可读性和可维护性也会得到提升。
答案 3 :(得分:1)
是的,因为当您选择文字时,它不需要从磁盘读取(甚至从缓存中读取)。
答案 4 :(得分:1)
在exists子句中选择的内容无关紧要。大多数人都选择*,然后sql server自动选择最佳索引
答案 5 :(得分:1)
有人指出sql server会忽略EXISTS中的列选择列表,所以没关系。我个人倾向于使用“SELECT null ...
”表示根本没有使用该值。
答案 6 :(得分:1)
如果你看一下
的执行计划select COUNT(1) from master..spt_values
并查看流聚合,您将看到它计算
Scalar Operator(Count(*))
因此1
实际上已转换为*
但是我在“Inside SQL Server”系列丛书中的某处读过*
可能会产生非常轻微的开销来检查列权限。不幸的是,正如我记得的那本书没有详细介绍。
答案 7 :(得分:-1)
选择1应该更适合在您的示例中使用。 Select *获取在运行时之前与对象相关联的所有元数据,这些元数据在编译查询期间会增加开销。虽然在执行计划中运行这两种类型的查询时可能看不到差异。