我正在使用SQL Server 2008R2。我已經編寫了下面的表值UDF,它接受標量值this或者this或者兩者作爲參數,並返回一個帶有列ID的表,this和那個表。當我從一個複雜的查詢中調用這個函數時,我看到了糟糕的表現,但當我在簡單的查詢中調用它時,卻看不到這種性能。我想知道是否有人對我正在做的事情有任何想法,這會減慢速度。函數的定義如下:內聯表值UDF性能
CREATE function dbo.fn_getThisThat (@this nvarchar(255), @that nvarchar(255))
RETURNS TABLE
RETURN
SELECT These.this, Those.that, COALESCE(These.ID, Those.ID) as ID
FROM
(
SELECT col1 as ‘this’, value1, value2, ID
FROM (
SELECT t1.col1, t1.col2, t1.col3, t2.col1
FROM t1
JOIN t2
ON t1.col1 = t2.col1
WHERE t2.col2 = ‘this’
AND t1.col1 in (‘value1’, ‘value2’)
) SOURCE
PIVOT (
MAX(t1.col3) FOR t1.col1 in (value1, value2)
) AS pvt
) These
JOIN
(
SELECT t1.col1, t1.col2, t2.col1, t3.ID
FROM t3
JOIN t1
ON t3.col1 = t1.col1
JOIN t2
ON t2.col1 = t1.col1
WHERE t3.col3 = ‘value3’
AND t1.col3 = ‘value1’
AND t2.col3 = ‘value2’
) Those
WHERE that = @that
OR this = @this
下面的語句過程非常迅速(< 1秒)時傳遞標量參數:
SELECT * FROM dbo.fn_getThisThat(scalarValue, null)
或者在像一個相對簡單的查詢:
SELECT t1.col1, t1.col2, fn.This
FROM t1
CROSS APPLY dbo.fn_getThisThat(t1.col3, null)
...但是在像這樣更復雜的查詢中調用時(在僞代碼中:讓我知道它是否沒有足夠的信息),它滯後HORRIBLY(從處理時間約1秒到約2:30秒):
DECLARE @table (a, b, c)
INSERT @table (a, b, c)
SELECT (values)
SELECT t1.c1, t1.c2, t1.c3
FROM
(
SELECT a.c1, COUNT(fn.That) as c2, COUNT(a.c2) as c3
FROM a
JOIN b ON (join terms)
CROSS APPLY dbo.fn_getThisThat(a.c2, null) fn
WHERE a.c1 IN (SELECT a FROM @table)
GROUP BY a.c1
) t1
有沒有人有什麼建議我在做什麼來殺死在這第二個查詢的速度?我改變了函數接受一個數組而不是標量參數,但是這消除了我的跨應用能力(在最後的代碼片段中)。就我從查詢分析器中可以看出的性能影響來自於我的函數的交叉應用。我以爲我不會遇到RBAR,因爲我的UDF不是多語言,但也許我是錯的......?
編輯: 還有一件事:查詢執行計劃顯示該函數本身只貢獻2%的批處理;較大的查詢貢獻了98%,但其大部分成本來自索引搜索和表掃描,而不是來自並行性。這使我認爲函數調用可能不是指責查詢緩慢的原因,而是某些表所涉及的索引缺乏(不幸的是,我並沒有很多控制權來增加指數)。我在沒有調用函數的情況下運行查詢,並且表掃描和索引查找仍顯示爲高,但查詢在大約8秒內完成。那麼,我們回到了功能......?
感謝您的建議:我不確定我可以在應用函數之前進行分組,因爲它作爲一個「翻譯器」將其轉換爲該函數,反之亦然。這個想法是計算這個數字並按照ID進行分組:只要我能夠確定我是否先嚐試將整數轉換爲這個或那個,這是行不通的。 – AnnStimmel