我遇到了表值函数性能的奇怪场景。基本上,我有一个内联表值函数,它将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调用这个表值函数,它不会声明一个临时变量。
有没有办法在内联表值函数中使用临时变量?我真的不想将它转换为多行表值函数。其他想法也会受到欢迎。我有点难过。
答案 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参数会以某种方式产生一个截然不同的执行计划。我很想知道原因。