Sql-Server

包含大量 ComputeScalar 操作的執行計劃

  • May 13, 2022

我使用和不使用 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

問題是編譯大量值可能需要很長時間:每個值都需要自己的虛擬表,結果是 aConstant Scan和 aCompute Scalar以及Concatenation最後的 big。這就是在執行查詢之前導致編譯時速度變慢的原因。

同時,該OPTION (RECOMPILE)版本可以將參數直接嵌入到查詢中,這意味著在編譯的優化階段甚至開始之前,這些值就會被折疊在一起,從而顯著加快了整體編譯時間。這是以每次執行時重新編譯為代價的。

所有這些的結果是非常長的IN列表以及大量參數可能非常低效。

我建議您改為考慮使用表值參數、臨時表或表變數(在所有情況下都使用主集群鍵索引)並以正常方式簡單地加入它們。


至於實際查詢本身,它有許多奇怪的東西。

  • 您的最終結果只是COUNT(*)不清楚巨人的重點是什麼PIVOT,而不是正常的GROUP BY.
  • 同樣,不清楚為什麼大多數表格都在那裡,或者最終結果應該表示什麼。
  • 一旦你解決了這個問題,為什麼LEFT JOIN而不是INNER JOIN?連接列是否可以為空?
  • CROSS APPLY實際上並沒有應用任何外部引用,它可能是,CROSS JOIN並且它本身在查詢中沒有任何用途。

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