2017-06-15 75 views
0

問題是:可以使用內聯表值函數(ITVF)來封裝和重用代碼嗎?或者這會導致性能問題?使用內聯表值函數封裝SQL代碼的性能

我研究聯表值函數,這使我這個討論: When would you use a table-valued function?

討論的回答指出值函數「內嵌表允許優化治療這些功能沒有區別對象他們封裝給你最佳的性能(假設你的索引和統計數據是理想的)。「

我最初的問題是,我試圖將不同的數據源重新格式化爲標準格式,然後將它們合併。我測試了聯合6個不同的ITVF,而不是在一個查詢中執行聯合和轉換。執行計劃是相同的。由於我的背景是在oop中,我寧願將查詢拆分成更小的函數,但在我承諾在將來的項目中這樣做時,我想知道是否使用過多的ITVF最終會導致性能問題。

+0

只是不要陷入這樣一種常見的誤解,即添加「RETURNS TABLE」使您的函數內聯。它必須只是一個單一的陳述。如果你有變量或者多行代碼,那麼性能將會非常糟糕......甚至比標量函數還要糟糕。 –

+0

@SeanLange什麼算作一個單一的陳述?是工會,交叉適用和子查詢是否考慮過一個或多個陳述? –

+0

這將是一個單一的陳述。如果你必須把開始/結束塊,你沒有內聯函數。如果你的函數定義是「... AS RETURN ...」,你的狀態良好。 :) –

回答

0

可以使用內聯表值函數(ITVF)來封裝和重用代碼嗎?

是的。它們在多語句TVF中的優越性在於,由於使用多語句TVF,封裝可以防止查詢優化器將謂詞推入TVF邏輯,並阻止它精確估計返回的行數。

或者這會導致性能問題?

簡短的回答,通常不會。

較長的答案:

有4種方式來封裝和重用查詢邏輯(整個查詢,而不只是標量表達式)。

  1. 查看
  2. 內嵌表值函數
  3. 多語句表值函數
  4. 臨時表
  5. 表變量

視圖和內聯TVFs本來不降低性能,但它們增加了查詢優化的複雜性。

凡優化不能始終如一地找到你可能需要干預的低成本計劃。一種常見的方法是強制後臺處理(即實現)中間結果,例如用多語句TVF替換Inline TVF,或者通過將結果提前後臺打包到臨時表中。在較大查詢的上下文中運行時

假脫機在封裝的查詢的可能的優化的成本降低了包封的查詢的複雜性。

當後臺的結果,臨時表通常是最好的,因爲SQL服務器也可以有索引和統計,使SQL Server來準確地評估,這將消耗中間結果的計劃的成本。

0

ITVF非常適合封裝查詢邏輯以便重複使用。我有十幾份財務報告,所有這些財務報表都查詢了大致相同的信息,並通過創建一個函數來提供這些數據,我可以肯定的是,我的所有報表都是從相同的數據體相同的過濾器和轉換等等。

也就是說,您也可以輕鬆創建一個視圖而不是ITVF,但ITVF還提供了一種基於發送的參數過濾或以其他方式轉換數據的方法。例如,我的財務職能可以接受區名作爲可選的輸入參數,並且只返回該區的數據。通過這種方式使用ITVF,優化器可以隨着時間的推移基於發送的參數優化查詢計劃,這有助於而不是阻礙性能。

我建議您不要在六個不同的ITVF上使用聯合,而只需將所有表一起拖放到一個ITVF中:如果您的表模式或報表需求發生更改,那麼只有一個地方可以進行更新。