将日期参数传递给内联表值函数的速度很慢

时间:2012-03-20 03:14:02

标签: sql sql-server-2008 sql-server-2005 tsql

我遇到了表值函数性能的奇怪场景。基本上,我有一个内联表值函数,它将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)

它在不到一秒的时间内运行。 SQL Server对两个调用使用完全不同的解释计划。

显然,我希望它一直在做第二种方法,不幸的是,我通过LINQ 2 SQL调用这个表值函数,它不会声明一个临时变量。

有没有办法在内联表值函数中使用临时变量?我真的不想将它转换为多行表值函数。其他想法也会受到欢迎。我有点难过。

2 个答案:

答案 0 :(得分:1)

我尝试了大量的记录,两种方式都在9秒内返回值,没有 差异...

这是一个很长的镜头,但可以测试一下隐式转换是否为函数提供与显式转换相同的日期值?试试像#2011; 1/30'所以你会有月/日转换问题

答案 1 :(得分: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)

在第二次调用中添加OPTION(RECOMPILE)可以解决问题。

据我所知,使用datetime参数会以某种方式产生一个截然不同的执行计划。我很想知道原因。