Sql-Server
包含大量 ComputeScalar 操作的執行計劃
我使用和不使用 OPTION (RECOMPILE) 執行了相同的查詢。當我比較這兩個計劃時,我看到的一個主要區別是沒有選項重新編譯的計劃顯示了很多 ComputeScalar 運算符,而另一個則沒有。
以下是兩個計劃:
不帶選項重新編譯: https ://www.brentozar.com/pastetheplan/?id=S1OcZGi85 帶選項重新編譯:https ://www.brentozar.com/pastetheplan/?id=ryJAfMsL5
為什麼一個計劃使用大量計算標量而另一個不使用?沒有選項 recompile 的查詢需要將近 4 分鐘才能執行。計算標量操作是否導致緩慢?
編譯器正在使用您的
IN
子句並嘗試通過刪除重複值來進行優化。它通過獲取所有參數、對它們進行排序、使用按順序合併它們並對結果Merge Interval
執行 a來做到這一點Nested Loop Join
。問題是編譯大量值可能需要很長時間:每個值都需要自己的虛擬表,結果是 a
Constant Scan
和 aCompute Scalar
以及Concatenation
最後的 big。這就是在執行查詢之前導致編譯時速度變慢的原因。同時,該
OPTION (RECOMPILE)
版本可以將參數直接嵌入到查詢中,這意味著在編譯的優化階段甚至開始之前,這些值就會被折疊在一起,從而顯著加快了整體編譯時間。這是以每次執行時重新編譯為代價的。所有這些的結果是非常長的
IN
列表以及大量參數可能非常低效。我建議您改為考慮使用表值參數、臨時表或表變數(在所有情況下都使用主集群鍵索引)並以正常方式簡單地加入它們。
至於實際查詢本身,它有許多奇怪的東西。
- 您的最終結果只是
COUNT(*)
不清楚巨人的重點是什麼PIVOT
,而不是正常的GROUP BY
.- 同樣,不清楚為什麼大多數表格都在那裡,或者最終結果應該表示什麼。
- 一旦你解決了這個問題,為什麼
LEFT JOIN
而不是INNER JOIN
?連接列是否可以為空?CROSS APPLY
實際上並沒有應用任何外部引用,它可能是,CROSS JOIN
並且它本身在查詢中沒有任何用途。