我正在尝试将内联TVF作为原始参数化SQL查询运行。
当我在SSMS中运行以下查询时,需要 2-3秒
select * from dbo.history('2/1/15','1/1/15','1/31/15',2,2021,default)
我能够通过SQL profiler捕获以下查询(参数化,由Entity框架生成)并在SSMS中运行它。
exec sp_executesql N'select * from dbo.history(@First,@DatedStart,@DatedEnd,@Number,@Year,default)',N'@First date,@DatedStart date,@DatedEnd date,@Maturity int,@Number decimal(10,5)',@First='2015-02-01',@DatedStart='2015-01-01',@DatedEnd='2015-01-31',@Year=2021,@Number=2
在SSMS中运行上述查询需要 1:08 ,这比非参数化版本长约30倍。
我尝试在参数化查询的末尾添加option(recompile)
,但就性能而言,它绝对没有做任何事情。这对我来说显然是一个索引问题,但我不知道如何解决它。
在查看执行计划时,似乎参数化版本大部分主要挂在 Eager Spool(46%)上,然后是 Clustered Index扫描(30%)< / em>在没有参数的执行计划中不存在。
也许有一些我缺少的东西,有人可以指出我正确的方向,以便我如何让这个参数化的查询正常工作?
编辑:Parameterized query execution plan,non-parameterized plan
答案 0 :(得分:2)
可能它是一个参数嗅探问题。
尝试修改函数,以便将参数设置为局部变量,并使用SQL中的本地变量而不是参数。
所以你的函数会有这个结构
CREATE FUNCTION history(
@First Date,
@DatedStart Date,
@DatedEnd Date,
@Maturity int,
@Number decimal(10,5))
RETURNS @table TABLE (
--tabledef
)
AS
BEGIN
Declare @FirstVar Date = @First
Declare @DatedStartVar Date = @DatedStart
Declare @DatedEndVar Date = @DatedEnd
Declare @MaturityVar int = @Maturity
Declare @NumberVar decimal(10,5) = @Number
--SQL Statement which uses the local 'Var' variables and not the parameters
RETURN;
END
我过去曾有类似的问题,这是罪魁祸首,映射到局部变量会阻止SQL Server提出dud执行计划。