2012-03-20 26 views
4

テーブル値関数のパフォーマンスで奇妙なシナリオがあります。基本的には、DATETIMEをパラメータとするインラインテーブル値関数があります。それは一種の、このようになります日付パラメータをインラインテーブル値関数に渡すことがありません

(ないまさにこのことを):

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) 

なお、第2の下で実行されます。 SQL Serverは、両方の呼び出しに対して全く異なる説明計画を使用しています。

明らかに、2番目の方法を常に実行したいと思いますが、残念ながら、LINQ 2 SQLを通じてこのテーブル値関数を呼び出していますが、これは中間変数を宣言しません。

インラインテーブル値関数で中間変数を使用する方法はありますか?私は本当にこれを複数行のテーブル値関数に変換したくありません。他のアイデアも歓迎されるでしょう。私は少し困惑しています。

+0

テストでは、 'SELECT * FROM fn_MyFunction( '7/1/2011')'を複数回実行しようとしましたか? –

+0

@ジョン。はい。数回。キャッシュの問題ではありません。 – Linus

+0

あなたにLINQを教えてください。 –

答えて

1

これはロングショットですが、暗黙のキャストが与えているかどうかを確認するためにテストすることができます...

を私は、レコードの大ammountでこれを試していないし、両方の方法は、9秒の値を返して、何 diference明示的なキャストと同じ日付の値を機能させますか? '2011/1/30'のような日付で試してみてください。月/日の変換に問題があります。

0

OPTION(RECOMPILE)を追加すると問題が解決します。次のように私は、インラインTVFと正確に同じ問題を持っている:

この文は、1秒未満で実行されます。

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) 

2番目の呼び出しにOPTION(RECOMPILE)を実行すると、問題が解決されます。

datetimeパラメータを使用してわかることから、何とか大幅に異なる実行計画が生成されます。理由を知ることに興味があります。

関連する問題