SQL Server:选择字面值比选择字段更快吗?

时间:2008-09-18 23:47:13

标签: sql sql-server

我看到有些人使用EXISTS (SELECT 1 FROM ...)而不是EXISTS (SELECT id FROM ...)作为优化 - 而不是查找并返回值,SQL Server可以简单地返回它给出的文字。

SELECT(1)总是更快吗?从表中选择一个值是否需要选择文字会避免的工作?

8 个答案:

答案 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 *获取在运行时之前与对象相关联的所有元数据,这些元数据在编译查询期间会增加开销。虽然在执行计划中运行这两种类型的查询时可能看不到差异。