本问题已经有最佳答案,请猛点这里访问。
我已经看到有人使用EXISTS (SELECT 1 FROM ...)而不是EXISTS (SELECT id FROM ...)作为优化-SQL Server可以直接返回给定的文字,而不是查找并返回值。
SELECT(1)总是更快吗? 从表中选择一个值是否需要避免选择文字的工作?
在SQL Server中,在EXISTS中使用SELECT 1还是SELECT *都没有影响。您实际上并没有返回行的内容,而是由WHERE子句确定的集合不是空的。尝试与SET STATISTICS IO ON并排运行查询,您可以证明这些方法是等效的。我个人更喜欢EXISTS中的SELECT *。
为了Google的缘故,我将使用与该问题相同的答案(使用Exists 1或Exists *的子查询)来更新此问题,因为(当前)错误答案被标记为已接受。注意,SQL标准实际上说通过*的EXISTS与常量相同。
不。这已经涵盖了数十亿次。 SQL Server很聪明,并且知道它已用于EXISTS,并且不向系统返回任何数据。
Quoth Microsoft:
http://technet.microsoft.com/zh-CN/library/ms189259.aspx?ppud=4
The select list of a subquery
introduced by EXISTS almost always
consists of an asterisk (*). There is
no reason to list column names because
you are just testing whether rows that
meet the conditions specified in the
subquery exist.
还有,不相信我吗?尝试运行以下命令:
1 2 3 4 5
| 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
1 2 3
| 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>. |
当您使用SELECT 1时,您会清楚地显示(向以后阅读代码的人员)您正在测试记录是否存在。即使没有性能提升(这将在后面讨论),代码可读性和可维护性也会有所提高。
如果您看一下执行计划
1
| SELECT COUNT(1) FROM master..spt_values |
并查看流聚合,您将看到它计算
1
| Scalar Operator(COUNT(*)) |
所以1实际上被转换为*
但是,我在" Inside SQL Server"系列丛书中的某处读到,*可能会导致检查列权限的开销非常小。不幸的是,我记得这本书没有比这更详细。
就像有人指出的那样,sql server忽略了EXISTS中的列选择列表,所以没关系。我个人倾向于使用" SELECT null ..."来表示根本不使用该值。
在existant子句中选择什么都无所谓大多数人会选择*,然后sql server会自动选择最佳索引
是的,因为当您选择文字时,它不需要从磁盘(甚至从缓存)中读取。
选择1应该更好地用于您的示例。 Select *获取运行时之前与对象相关联的所有元数据,这会在查询完成时增加开销。尽管在执行计划中运行两种类型的查询时可能看不到差异。