SQL Server 2012存储过程运行缓慢

时间:2015-11-09 21:16:57

标签: sql sql-server sql-server-2012

我有一个SQL Server存储过程,它在SQL Server 2008 R2上运行良好。

当我尝试在SQL Server 2012上运行它时,运行需要很长时间。

但是如果我在存储过程中创建局部变量并将输入参数的值复制到那些局部变量中并使用它们而不是输入参数,查询运行并返回结果比SQL Server 2008 R2数据库更快(请注意2008年R2和2012服务器在同一个盒子上运行。)

请您详细了解这里发生的事情?

1 个答案:

答案 0 :(得分:7)

通过创建局部变量并重新绑定值,您可以停用 parameter sniffing

  

参数嗅探是SQL Server创建的过程   使用调用参数的存储过程的最佳计划   在第一次执行存储过程时传递

     

对具有相同参数的相同商店流程的每次后续调用也将获得最佳计划,而具有不同参数值的调用可能无法始终获得最佳计划

慢跑:

CREATE PROC [dbo].[DisplayBillingInfo]
  @BeginDate DATETIME,
  @EndDate DATETIME
AS
BEGIN
  SELECT BillingDate, BillingAmt
  FROM BillingInfo
  WHERE BillingDate between @StartDate AND @StopDate; 
END

快跑(因为每次必须计算新的执行计划):

CREATE PROC [dbo].[DisplayBillingInfo]
  @BeginDate DATETIME,
  @EndDate DATETIME
AS
BEGIN
  DECLARE @StartDate DATETIME = @BeginDate;
  DECLARE @StopDate DATETIME = @EndDate;

  SELECT BillingDate, BillingAmt
  FROM BillingInfo
  WHERE BillingDate between @StartDate AND @StopDate; 
END

案例是SQL Server优化器无法重用缓存计划并每次评估它。

这与您使用WITH RECOMPILE相同:

CREATE PROC [dbo].[DisplayBillingInfo]
  @BeginDate DATETIME,
  @EndDate DATETIME
WITH RECOMPILE
AS
BEGIN
  SELECT BillingDate, BillingAmt
  FROM BillingInfo
  WHERE BillingDate between @StartDate AND @StopDate; 
END

使用查询提示:

CREATE PROC [dbo].[DisplayBillingInfo]
  @BeginDate DATETIME,
  @EndDate DATETIME
AS
BEGIN
  SELECT BillingDate, BillingAmt
  FROM BillingInfo
  WHERE BillingDate between @StartDate AND @StopDate
  OPTION(RECOMPILE);
  -- OPTION (OPTIMIZE FOR (@StartDate UNKNOWN, @StopDate UNKNOWN))
END