2012-03-20 95 views
4

我有一個表值函數的性能奇怪的情況。基本上,我有一個內聯的表值函數,它將DATETIME作爲參數。將日期參數傳遞到內聯表值函數是sloooww

它看起來有點像這樣(不完全這樣):

CREATE FUNCTION fn_MyFunction(@StartDate DATETIME) 
    RETURNS TABLE 
    AS 
    RETURN (
    SELECT COUNT(*), CustomerID, SUM(PAID) 
    FROM Orders 
    WHERE OrderDate > @StartDate 
    GROUP BY CustomerID 
) 

現在,我想調查這哪裏查詢運行>1分鐘的問題。事實證明,如果我這樣稱呼查詢:

SELECT * FROM fn_MyFunction('7/1/2011') 

運行時間> 1分鐘。

但是,如果我打電話查詢是這樣的:

DECLARE @startDate DATETIME = '7/1/2011' 
SELECT * FROM fn_MyFunction(@startDate) 

它運行在第二下。 SQL Server對兩個調用都使用完全不同的解釋計劃。

很顯然,我希望它一直做第二種方法,不幸的是,我通過LINQ 2 SQL調用這個表值函數,它不會聲明臨時變量。

有沒有一種方法可以在內聯表值函數中使用臨時變量?我真的不想將它轉換爲多行表值函數。其他想法也會受到歡迎。我有點難住。

+0

在您的測試中,您是否嘗試過多次運行'SELECT * FROM fn_MyFunction('7/1/2011')'? – 2012-03-20 04:50:00

+0

@John。是。幾次。不是緩存問題。 – Linus 2012-03-20 12:02:32

+0

向我們展示你的LINQ。 – 2012-03-21 15:41:52

回答

1

我試圖與大ammount的記錄和左右逢源9秒的返回值,沒有 性差異...

這是一個長鏡頭,但可以測試,看看是否隱式轉換爲給與顯式類型轉換功能相同的日期值?嘗試使用像'2011/1/30'這樣的日期,以便您有月/日轉換問題

0

添加OPTION(RECOMPILE)將解決您的問題。我有一個內嵌TVF完全相同的問題如下:

這種說法在執行不到一秒鐘:

select PropertyID from msa_GetPropertlyListWithNoMessages_TVF(DATEADD(hh, -2, Getdate())) 

這種說法從來沒有執行完畢後5小時:

declare @msg_age as Datetime 
SET @msg_age = DATEADD(hh, -2, Getdate()) 
select PropertyID from msa_GetPropertlyListWithNoMessages_TVF(@msg_age) 

添加對第二個電話的選項(RECOMPILE)糾正了問題。

從我可以告訴使用datetime參數不知何故產生一個截然不同的執行計劃。我會有興趣找出原因。