T-Sql

與內聯子查詢相比,使用交叉應用或 CTE 沒有優勢

  • July 10, 2015

我遇到了這樣的查詢:

SELECT (SELECT COUNT(1) FROM Orders o WHERE i.ItemId = o.ItemId) [C]
FROM Items i

我將其更改為以下

;WITH cte_count
AS
(
   SELECT COUNT(1) c, OrderId FROM Orders Group By ItemId
)
SELECT a.c [Count], i.Name
FROM Items i
INNER JOIN cte_count c ON (c.ItemId = i.ItemId)

但兩者的執行計劃如下所示:

CTE 和內聯執行計劃

同樣,還有另一個查詢選擇TOP 1 Order By Id。我嘗試將這個移到CROSS APPLY但是對於這個,我也有相同的執行計劃。

交叉應用和內聯執行計劃

當然,查詢中還有其他連接和列。

我的困境是關於使用CROSS APPLYand的實用性和優勢CTE。有沒有或只是異國情調?

但兩者的執行計劃如下所示:

計劃不同。一種是內連接,另一種是外連接。在您的簡單測試中,結果可能相同,但語義不同。在更複雜的查詢中,這種差異可能會導致更明顯的不同執行計劃,並帶來性能影響。

通常有很多方法可以在 SQL 中表達相同的要求(或類似的要求,如您的範例)。您使用的最初是偏好和風格的問題。在某些情況下,使用其中一種會產生重要的性能差異,因為聲明性 SQL 通過優化器採用不同的程式碼路徑。在這種特殊情況下,外連接可能無法很好地發揮優化器的探索能力(與內連接相比,外連接使用的工具更少)。

使用不同的語法重寫查詢以定義相同的結果可能是一種有效的調整方法,但它需要仔細注意細節並在 SQL Server 修補或升級時重新測試。通常沒有理由更喜歡用 SQL 表達需求的一種方式而不是另一種。

此外,正如 Andriy 在對您問題的另一份副本的評論中提到的那樣,“在更一般的情況下,您的內聯查詢每行只會給您一個結果,同時加入 CTE(不一定是CTE,它可以是普通的子選擇)或 CROSS APPLY 行集可以讓您訪問多個列。”

引用自:https://dba.stackexchange.com/questions/106534