2013-03-06 64 views
1

我遇到了一個存儲過程,它有一些故障。一個是,開發商這樣做:直接查詢或子查詢之間的區別?

SELECT alias.firstname, alias.surname, alias.id 
FROM 
    (SELECT firstname, surname, id, address, anotherfield, etc, etc 
    FROM TableName 
    WHERE afield = avalue) alias 

所以,這顯然是一樣的:

SELECT firstname, surname, id 
    FROM TableName 
    WHERE afield = avalue 

這重複了很多。所以,我的問題是,執行子查詢會有性能損失嗎?我知道這是無用的......最好的想法是做對 - 我做了。但是,離開它會有什麼性能損失嗎?

我猜查詢優化器會理解它,並做正確的事情?

回答

2

在這種簡單的情況下,SQL Server會將這些查詢合併到同一個執行計劃中。

我想這對AdventureWorks2012:

SELECT CarrierTrackingNumber, ProductID, UnitPrice, LineTotal 
FROM 
(
    SELECT * 
    FROM Sales.SalesOrderDetail 
    WHERE ProductID = 781 
) AS Alias; 

SELECT CarrierTrackingNumber, ProductID, UnitPrice, LineTotal 
FROM Sales.SalesOrderDetail 
    WHERE ProductID = 781; 

的計劃是相同的,並且在運行指標的差異是無法區分的。

enter image description here

我也試過以下,有意選擇具有複雜的類型(地理)的表:

SELECT AddressLine1, City, StateProvinceID 
FROM Person.Address 
    WHERE StateProvinceID = 9; 

SELECT AddressLine1, City, StateProvinceID 
FROM 
(
    SELECT * FROM Person.Address 
    WHERE StateProvinceID = 9 
) AS x; 

SELECT AddressLine1, City, StateProvinceID 
FROM 
(
    SELECT * FROM Person.Address 
) AS x 
WHERE StateProvinceID = 9; 

同樣的事情,在每種情況下,優化器合攏爲索引掃描,而忽略出現其他列引用:

enter image description here

是否可以依賴於T他在更復雜的查詢中發生的同樣的優化,我不確定。優化器並不總是完美或可預測的......所以我可以肯定地預見更多涉及的查詢,這種崩潰不會可靠地發生。

我不確定我瞭解您所看到的模式的價值。也許有些例子實際上有助於某種目的。

+0

謝謝@Aaron,這是一個了不起的答覆,非常有幫助。我所看到的查詢的原因純粹是開發人員誤解了老年人的指導。問題是,這是做了很多...非常簡單的查詢,這樣做。要全部改變它們,需要重新測試。所以,我改變了一些,但現在想知道在時間成本計算方面是否繼續改變它們是有用的。沒有性能損失=離開它。你的回覆已經回答了。謝謝! – Craig 2013-03-06 03:08:56

1

這兩個查詢的執行計劃在性能方面是相同的。優化器只會拋出未使用的列。

2

在外部查詢中只涉及projection的情況下,這兩個查詢之間的執行計劃應該完全沒有區別。在內部查詢和外部查詢中使用「where」子句的更復雜的查詢可能會測試查詢優化器的限制,並可能爲兩級查詢產生較差的查詢計劃,但在您的情況下,計劃和執行速度應該是相同。