2008-09-18 102 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」系列書籍*可能遭受非常輕微的開銷檢查列權限已閱讀的地方。不幸的是,這本書沒有比我記得的更詳細。