2013-11-09 71 views
3

雖然這是一個相當主觀的問題,但我覺得有必要在這個論壇上分享。爲什麼SQL函數比UDF更快

我個人經歷過,當我創建一個UDF(即使這並不複雜)並將其用於我的SQL時,它會大幅降低性能。但是當我使用SQL inbuild function時,他們碰巧工作得更快。轉換,邏輯&字符串函數是明確的例子。

所以,我的問題是「爲什麼構建函數中的SQL比UDF快?」?如果有人能指導我如何從數學上或邏輯上判斷/操縱功能成本,那將是一個優勢。

+0

'user-defined function'是什麼意思?你是指用'CREATE FUNCTION'創建的函數,還是用C或C++編寫的函數,並且動態地或在編譯時包含這些函數? – 2013-11-09 23:04:36

+1

許多內置函數都是作爲查詢計劃中的特殊操作符(例如,標準聚合器或窗口函數)實現的,或者很簡單,以至於它們不會很慢。 – siride

回答

3

這是SQL Server中標量UDF的一個衆所周知的問題。

它們沒有內聯到計劃中,並且調用它們會增加內部開銷,而不是相同的內聯邏輯。

下只需要在2秒我的機器

WITH T10(N) AS 
(
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
    SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
) --10 rows          
, T(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) 
      FROM T10 a, T10 b, T10 c, T10 d, T10 e, T10 f, T10 g) -- 10 million rows 
SELECT MAX(N - N) 
FROM T 
OPTION (MAXDOP 1) 

創建簡單的標量UDF

CREATE FUNCTION dbo.F1 (@N BIGINT) 
RETURNS BIGINT 
WITH SCHEMABINDING 
AS 
BEGIN 
RETURN (@N - @N) 
END 

和更改查詢MAX(dbo.F1(N)),而不是MAX(N - N)STATISTICS TIME OFF和需要約26秒37一起。

1000萬次函數調用的平均每次增加2.6μs/3.7μs。

運行Visual Studio分析器顯示絕大多數時間都在UDFInvoke之下。調用堆棧中的方法的名稱提供了額外開銷(複製參數,執行語句,設置安全上下文)的額外內容。

enter image description here

移動邏輯到內嵌表值函數

CREATE FUNCTION dbo.F2 (@N BIGINT) 
RETURNS TABLE 
RETURN(SELECT @N - @N AS X) 

,改寫查詢作爲

SELECT MAX(X) 
FROM Nums 
CROSS APPLY dbo.F2(N) 

執行一樣快的時間內完成原始查詢不使用任何功能。

相關問題