sql-server - 使用参数化查询时 TVF 速度要慢得多

标签 sql-server sql-server-2008 user-defined-functions sqlperformance sql-optimization

我正在尝试将内联 TVF 作为原始参数化 SQL 查询运行。

当我在 SSMS 中运行以下查询时,需要2-3 秒

select * from dbo.history('2/1/15','1/1/15','1/31/15',2,2021,default)

我能够通过 SQL 探查器(参数化,由 Entity Framework 生成)捕获以下查询并在 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%)上,然后是聚集索引扫描(30%) 不存在于不带参数的执行计划中。

也许我缺少一些东西,有人可以给我指出正确的方向,告诉我如何让这个参数化查询正常工作吗?

编辑:Parameterized query execution plan , non-parameterized plan

最佳答案

可能是参数嗅探问题。

尝试修改您的函数,以便将参数设置为局部变量,并在 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 提出无用的执行计划。

关于sql-server - 使用参数化查询时 TVF 速度要慢得多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30792325/

相关文章:

sql-server-2008 - 启用 'xp_cmdshell' SQL Server

php - 如何在php中编写mysql用户自定义函数

php - 如何在 PHP 中使用带有 PDO 的 MySQL 用户函数?

sql - 用于计算动态表项目的 MS SQL 存储过程

SQL Server : SUM() with GROUP BY

java - 尝试获取新插入行的 id 时出现异常

sql-server - 将 SQL Server 2008 db 复制到 SQL Server 2008 Express 的工具?

PostgreSQL - 如何使用动态参数定义用户定义的函数?

sql-server - 为什么用户定义的表类型的默认值不会保留在数据库中?

.net - 通过WMI每秒监视SQL Server上的批处理请求