3

我有一个存储过程,它在其中使用一个函数,并且该函数需要两个参数。我的问题与性能问题有关,见下文

 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

然后,您可以重写存储过程以使用它。

但是,在编写查询时,确定性函数只会为 datediff 返回 0,因为这两个参数是相同的。

最后,您的性能问题似乎与被调用的函数有关。您发布代码的建议是一个很好的建议。

于 2012-04-30T14:41:48.750 回答