2009-01-27 116 views
22

在Sql Server 2005中,當我有多個參數時,我是否保證評估順序將始終爲是從左到右?選擇「where子句」評估順序

使用的一個示例:

select a from table where c=1 and d=2

在該查詢中,如果 「C = 1」 狀態失敗 「d = 2」 條件將永遠不會被評估?

PS-「c」是一個整數索引列,d是一個大的varchar和非可索引的列,需要全表掃描

更新我試圖避免執行兩個查詢或條件語句,我只需要這樣的:如果「c條件」失敗,有一種方法可以避免執行沉重的「d條件」,因爲在我的情況下不需要。

回答

26

評估訂單不保證。優化器將嘗試使用可用信息找到執行查詢的最有效方法。

對於你的情況,由於c是索引,而d不是,所以優化器應該查找索引來查找匹配c上謂詞的所有行,然後從表數據中檢索這些行以評估d上的謂詞。

但是,如果它確定c上的索引不是非常有選擇性的(儘管在你的例子中沒有,性別列很少有用的索引),它可能決定進行表掃描。

要確定執行順序,您應該爲您的查詢得到解釋計劃。但是,要意識到該計劃可能會根據優化程序認爲的最佳查詢而改變。

4

SQL Server將爲其執行的每個語句生成一個優化計劃。您不必爲了獲得該收益而訂購Where子句。您所擁有的唯一Garuntee是它將按如下順序運行語句:

SELECT A FROM B WHERE C 
SELECT D FROM E WHERE F 

將在第二行之前運行第一行。

+1

換句話說:NO。 SQL Server會以它認爲最快的方式重新排列你的條件。如果你的條件有副作用(可能通過udf函數調用),這可能會導致問題。 – 2009-01-27 16:56:45

+2

將UDF放入WHERE子句可能會非常緩慢。我們或多或少不得不取締他們的表現如此糟糕。 – Joe 2009-01-27 16:59:57

+0

這不太正確。 – 2009-01-27 17:27:04

2

您可以查看查詢的執行計劃並確定它實際正在嘗試執行的操作。我認爲SQL Server的查詢引擎應該進行這種類型的掃描,並將其智能地轉換爲操作。就像,如果你做的「昂貴和虛假」,它會很快評估爲假。

從我所學到的,你輸入的內容(和可能)與實際執行的不同。你只是告訴服務器你期待什麼類型的結果。它如何得到答案並不關聯你提供的代碼的從左到右。

1

控制評估順序的一種方法是使用CASE表達式。

[編輯]

流行的觀點,我想表達是:

你不能依賴於表達式求值順序的東西像 「WHERE OR」,因爲優化器可能會選擇一個計劃 評估第一個謂詞之前的第二個謂詞。但是 CASE語句中表達式的評估順序是固定的,因此您可以依賴CASE 語句的確定性短路評估。

它確實會有點比下面的網站作爲解釋更復雜:

http://blogs.msdn.com/b/bartd/archive/2011/03/03/don-t-depend-on-expression-short-circuiting-in-t-sql-not-even-with-case.aspx

2

如果你想確保你可以檢查Query Execution Plan。 MSSQL構建/優化的執行計劃足夠智能,可以在varchar列之前檢查索引列。

1

MS SQL Server查詢優化器確實會短路,是的。保證。

運行以下命令:

select 1 where 1 = 0 and 1/0 = 10 

它將運行得很好,沒有錯誤,即使你被零除,因爲查詢優化器將短路評價where子句。這對任何where子句都有影響,你在哪裏「and」-ing,其中一個部分是常量。

1

當我們引用的條件只包含文字或常量時,就會完成短路。因此,例如讓我們說我們有一個TableA,它有列號爲1到10的所有正數,然後如果我寫這個查詢。

從表A中選擇NUM WHERE TableA.num < 0 AND 1/0 = 10。

它會導致錯誤。

編譯器是否足夠聰明以確定我的第二個子句是由常量組成的,因此它應該在評估子句之前評估該子句,該子句需要從表或索引進行任何掃描?