2008-09-18 69 views
1

我见过一些人使用EXISTS (SELECT 1 FROM ...)而不是EXISTS (SELECT id FROM ...)作为优化 - 而不是查找并返回一个值,SQL Server可以简单地返回它给出的文字。SQL Server:选择字面值比选择字段更快吗?

是否SELECT(1)总是比较快?如果从表中选择一个值需要工作,选择一个文字会避免?

回答

6

对于谷歌的缘故,我将用与此相同的答案更新此问题(Subquery using Exists 1 or Exists *),因为(当前)不正确的答案被标记为接受。请注意,SQL标准实际上表示通过*的EXISTS与常量相同。

不,这已经涵盖了bazillion倍。 SQL Server非常聪明,知道它正在用于EXISTS,并将NO DATA返回给系统。

答曰微软: http://technet.microsoft.com/en-us/library/ms189259.aspx?ppud=4

通过引入子查询 的选择列表中存在几乎总是 由星号(*)的。 没有理由列出列名,因为 您只是测试是否存在 满足 子查询中指定条件的行。

另外,不要相信我?尝试运行以下内容:

SELECT whatever 
    FROM yourtable 
WHERE EXISTS(SELECT 1/0 
       FROM someothertable 
       WHERE a_valid_clause) 

如果实际上正在使用SELECT列表,它会抛出一个由零错误的div。它没有。

编辑:请注意,SQL标准实际上谈到这一点。

ANSI SQL 1992年标准,第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>. 
+0

感谢您的跟进。接受的答案已更改。 – TSomKes 2010-12-03 17:09:43

1

是的,因为当你选择一个文字时,它不需要从磁盘读取(甚至不需要从缓存中读取)。

+2

这是错误的,请参阅:http://stackoverflow.com/questions/1597442/subquery-using-exists-1-or-exists/ – 2009-10-21 18:24:23

1

无论您在存在子句中选择什么。大多数人选择*,然后sql server会自动选择最佳索引

4

当您使用SELECT 1时,您清楚地显示(对于正在阅读您的代码的人)您是测试记录是否存在。即使没有性能增益(这是要讨论的),代码可读性和可维护性也有所增加。

+0

这是一个很好的观点。这个问题有点偏离主题,但我同意这个想法。 – TSomKes 2008-09-19 03:19:01

-1

选择1应该更好用在你的例子中。选择*在运行前获取与对象关联的所有元数据,这在查询的合成过程中会产生开销。尽管在执行计划中运行这两种类型的查询时可能看不到差异。

8

在SQL Server中,在EXISTS内使用SELECT 1还是SELECT *并没有什么不同。你实际上并没有返回行的内容,而是由WHERE子句确定的集合不是空的。尝试与SET STATISTICS IO ON并行运行查询,您可以证明这些方法是等效的。我个人更喜欢EXISTS内的SELECT *

+0

同意。我只是发现WHERE EXISTS(SELECT * FROM ...)更具可读性。这更直观 - 你只是检查记录是否存在而已。 WHERE EXISTS(SELECT 1 FROM ...)看起来不自然。当然,所有的主观意见。 – njr101 2008-09-22 10:20:05

1

正如有人指出sql服务器忽略EXISTS中的列选择列表,所以没关系。我个人倾向于使用“SELECT null ...”来表示根本不使用该值。

1

如果你看的执行计划

select COUNT(1) from master..spt_values 

,并期待在流合计,你会看到,它计算

Scalar Operator(Count(*)) 

所以1实际上被转换为*

不过,我在“内部的SQL Server”系列书籍*可能遭受非常轻微的开销检查列权限已阅读的地方。不幸的是,这本书没有比我记得的更详细。