Sql-Server

有沒有辦法防止計算列中的標量 UDF 抑制並行性?

  • October 26, 2017

有關SQL Server中標量 UDF的危險的文章很多。隨意搜尋會返回大量結果。

不過,在某些地方,標量 UDF 是唯一的選擇。

例如:在處理 XML 時:XQuery 不能用作計算列定義。Microsoft 記錄的一種選擇是使用標量 UDF將 XQuery 封裝在標量 UDF 中,然後在計算列中使用它。

這有各種影響和一些解決方法。

  • 查詢表時逐行執行
  • 強制對錶的所有查詢串列執行

您可以通過模式綁定函式來繞過逐行執行,並保留計算列或對其進行索引。即使沒有引用標量 UDF,這些方法都不能阻止對錶的查詢的強制序列化。

有沒有已知的方法可以做到這一點?

是的,如果您:

  • 正在執行 SQL Server 2014 或更高版本;和
  • 能夠在跟踪標誌 176處於活動狀態的情況下執行查詢;和
  • 計算列是PERSISTED

具體來說,至少需要以下版本:

  • SQL Server 2016 SP1 的累積更新 2
  • SQL Server 2016 RTM 的累積更新 4
  • SQL Server 2014 SP2 的累積更新 6

但是為了避免這些修復中引入的錯誤(參考20142016 和 2017 ),請改為應用:

跟踪標誌作為啟動–T選項有效,在全域和會話範圍內使用DBCC TRACEON,以及使用OPTION (QUERYTRACEON)計劃指南的每個查詢。

跟踪標誌 176 防止持久計算列擴展。

編譯查詢時執行的初始元數據載入會引入所有列,而不僅僅是那些直接引用的列。這使得所有計算列定義都可用於匹配,這通常是一件好事。

作為一個不幸的副作用,如果載入的(計算的)列之一使用標量使用者定義函式,它的存在會禁用整個查詢的並行性,即使計算的列實際上沒有被使用

跟踪標誌 176 有助於解決此問題,如果列是持久的,則不載入定義(因為跳過了擴展)。這樣,使用者定義的標量函式就不會出現在編譯查詢樹中,因此不會禁用並行性。

跟踪標誌 176 的主要缺點(除了很少記錄之外)是它還阻止查詢表達式匹配到持久計算列:如果查詢包含與持久計算列匹配的表達式,跟踪標誌 176 將防止表達式被替換為對計算列的引用。

有關更多詳細資訊,請參閱我的 SQLPerformance.com 文章Properly Persisted Computed Columns

由於問題提到了 XML,作為使用計算列和標量函式提升值的替代方法,您還可以查看使用 Selective XML Index,正如您在Selective XML Indexes: Not Bad At All中所寫的那樣。

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