3

内部で関数を使用しているストアドプロシージャがあり、関数は2つのパラメーターを期待しています。私の問題はパフォーマンスの問題に関連しています。以下を参照してください

 CASE 
 WHEN (DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeID), dbo.FunctionName(DatetimeField, DatetimeID))/60.0) > 8 THEN
      (DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeID), dbo.FunctionName(DatetimeField, DatetimeID))/60.0)
 Else 0
 END 
 Else
 0
 END)
 Else
(DATEDIFF(MINUTE,dbo.FunctionName(DatetimeField, DatetimeID), dbo.FunctionName(DatetimeField, DatetimeID))/60.0)-T.lunch
END
     as 'Total'

今、私がやりたいのは、一時テーブルを作成することです。これを使用して、数十万のレコードが通過する行に到達するたびに関数を呼び出す方法ではなく、関数を呼び出すことができます。どんな助けでも大歓迎です。

4

2 に答える 2

1

次のように、クエリ内で式を再利用できます。

select (case when NewValue > 8 then NewValue else 0 end) xyz
from T
cross apply (
 select NewValue = dbo.FunctionName(DatetimeField, DatetimeID)
) x

この特定の方法で使用されるクロス適用を使用して、新しい列を導入し、それらの値を再利用できます。この手法は、同じクエリで共通の式を再利用する場合に適しています。

通常のバッチ レベルの変数は、次のように宣言できます。

DECLARE @NewValue int = dbo.FunctionName(DatetimeField, DatetimeID);
于 2012-04-29T22:51:34.037 に答える
0

関数が決定論的である (または少なくとも時刻に関係なく同じ値を返す) と仮定すると、次のような一時テーブルを設定できます。

select DatetimeField, DatetimeID, FunctionName(DatetimeField, DatetimeID) as val
into #tmp
from (select distinct DatetimeField, DatetimeID
      from table
     ) t

その後、これを使用するようにストアド プロシージャを書き直すことができます。

ただし、クエリを作成すると、2 つの引数が同じであるため、決定論的関数は datediff に対して単純に 0 を返します。

結局、パフォーマンスの問題は、呼び出されている関数に関連しているようです。コードを投稿するという提案は良いものです。

于 2012-04-30T14:41:48.750 に答える