雖然這是一個相當主觀的問題,但我覺得有必要在這個論壇上分享。爲什麼SQL函數比UDF更快
我個人經歷過,當我創建一個UDF(即使這並不複雜)並將其用於我的SQL時,它會大幅降低性能。但是當我使用SQL inbuild function時,他們碰巧工作得更快。轉換,邏輯&字符串函數是明確的例子。
所以,我的問題是「爲什麼構建函數中的SQL比UDF快?」?如果有人能指導我如何從數學上或邏輯上判斷/操縱功能成本,那將是一個優勢。
雖然這是一個相當主觀的問題,但我覺得有必要在這個論壇上分享。爲什麼SQL函數比UDF更快
我個人經歷過,當我創建一個UDF(即使這並不複雜)並將其用於我的SQL時,它會大幅降低性能。但是當我使用SQL inbuild function時,他們碰巧工作得更快。轉換,邏輯&字符串函數是明確的例子。
所以,我的問題是「爲什麼構建函數中的SQL比UDF快?」?如果有人能指導我如何從數學上或邏輯上判斷/操縱功能成本,那將是一個優勢。
這是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
之下。調用堆棧中的方法的名稱提供了額外開銷(複製參數,執行語句,設置安全上下文)的額外內容。
移動邏輯到內嵌表值函數
CREATE FUNCTION dbo.F2 (@N BIGINT)
RETURNS TABLE
RETURN(SELECT @N - @N AS X)
,改寫查詢作爲
SELECT MAX(X)
FROM Nums
CROSS APPLY dbo.F2(N)
執行一樣快的時間內完成原始查詢不使用任何功能。
'user-defined function'是什麼意思?你是指用'CREATE FUNCTION'創建的函數,還是用C或C++編寫的函數,並且動態地或在編譯時包含這些函數? – 2013-11-09 23:04:36
許多內置函數都是作爲查詢計劃中的特殊操作符(例如,標準聚合器或窗口函數)實現的,或者很簡單,以至於它們不會很慢。 – siride