2009-07-03 72 views
4

我有一個相當龐大的查詢需要在幾個存儲過程中,我想將它轉換爲一個UDF,以便更容易維護(視圖將無法工作,這需要一堆參數),然而,我曾與之交談過的每個人都告訴我,UDF的速度非常慢。雖然我不知道究竟是什麼使它們變慢,但我會猜測它們是,但是由於我在連接中不使用此UDF,而是返回表變量,所以我認爲它不會那麼糟糕。SQLServer:爲什麼要避免表值用戶定義函數?

所以我想問題是,我應該不惜一切代價避免UDF?任何人都可以指出具體的證據表明他們更慢?

+0

你可以發佈一些或所有你所問的UDF嗎?它是內聯表UDF還是多行? – 2009-07-04 00:01:04

+0

多行UDF,但不能發佈代碼。 – FlySwat 2009-07-04 00:37:35

+0

UDF似乎變得糟糕的說唱。我們廣泛使用表值UDF來針對大數據集進行一些複雜的計算。表現非常出色。我們的許多UDF也是多線的,在我們的案例中,似乎並不影響性能。 – 2009-10-21 21:15:07

回答

-2

是否有某些原因,您不想使用stored procedure而不是UDF?

+0

主要是因爲你不能在SQLServer中做到這一點,所以你必須將sproc的返回插入到臨時表中。 – FlySwat 2009-07-03 23:20:47

+0

對不起,SQL Server中不能做什麼?存儲過程可以調用另一個存儲過程。 – 2009-07-03 23:55:46

3

正如您所指出的,(表格)udf的結果將不會加入任何內容,那麼不應對性能產生任何影響。

爲了試圖解釋一下爲什麼UDF可以被認爲是很慢的(實際上只是以錯誤的方式使用),請考慮下面的例子;

我們有表A和B表假設我們有一個像

聯接選擇 A.col1, A.col2, B.ColWhatever FROM 一個 JOIN B ON A.aid = B .fk_aid WHERE B.someCol = @參數1和A.anotherCol = @參數2

在這種情況下,SQL Server將做到這一點,最好在它知道如何最高效的方式返回結果。其中一個主要因素是減少磁盤讀取。因此 - 它將使用JOIN和where子句中的條件來評估(希望通過索引)返回多少行。

現在 - 比方說我們提取了一部分用來抵消返回給UDF的數據的條件。現在 - 查詢優化器不能再從磁盤中取回最小數量的行,它只能處理它提供的條件。簡而言之 - 一個表udf總是被評估,並且在返回到主sproc之前返回數據,因此,如果原始聯接中還有其他一些標準可能會導致更少的磁盤讀取 - 這隻會應用於數據被拉入存儲器後。

所以說,我們創建一個UDF來選擇表B中匹配where子句的行。如果表B中有100k行,並且其中50%符合where子句的條件,則所有這些行將返回到存儲過程以與表A比較。現在如果只有10%的人在表A中有匹配,那麼現在我們只與我們想要合作的B表的5%進行對話,但我們已經拉回了50%,其中大部分我們不想要!

如果這是作爲完整的胡言亂語道歉 - 請讓我知道!

0

你可以發佈你的代碼嗎?一般來說,如果您在查詢的select子句中使用標量udf,則udf中的語句將在查詢返回的每行中執行一次。對一個udf表進行聯接會更好,或者找到某種方法在你的udf中使用主SQL語句中的聯接執行邏輯。

相關問題