SQL Server 2012存储过程运行缓慢
我有一个SQL Server存储过程,它在SQL Server 2008 R2上运行良好 当我尝试在SQLServer2012上运行它时,它需要很长时间才能运行 但是,如果我在存储过程中创建局部变量,并将输入参数的值复制到这些局部变量中,并使用它们而不是输入参数,则查询运行和返回结果的速度要比SQL Server 2008 R2数据库快(请注意,2008 R2和2012服务器都在同一个框中运行)SQL Server 2012存储过程运行缓慢,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有一个SQL Server存储过程,它在SQL Server 2008 R2上运行良好 当我尝试在SQLServer2012上运行它时,它需要很长时间才能运行 但是,如果我在存储过程中创建局部变量,并将输入参数的值复制到这些局部变量中,并使用它们而不是输入参数,则查询运行和返回结果的速度要比SQL Server 2008 R2数据库快(请注意,2008 R2和2012服务器都在同一个框中运行) 您能解释一下这里发生了什么吗?通过创建局部变量并重新绑定您禁用的值: 参数嗅探是SQL Server
您能解释一下这里发生了什么吗?通过创建局部变量并重新绑定您禁用的值: 参数嗅探是SQL Server创建 使用调用参数优化存储过程的计划 第一次执行存储过程时传递的 使用相同参数对同一存储过程的每次后续调用也将得到一个最优计划,而使用不同参数值的调用可能并不总是得到一个最优计划 运行速度减慢:
CREATE PROC [dbo].[DisplayBillingInfo]
@BeginDate DATETIME,
@EndDate DATETIME
AS
BEGIN
SELECT BillingDate, BillingAmt
FROM BillingInfo
WHERE BillingDate between @StartDate AND @StopDate;
END
快速运行(因为每次都必须计算新的执行计划):
情况是SQL Server optimizer无法重用缓存的计划并每次对其进行评估
这与您在重新编译时使用的相同:
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
通过创建局部变量并重新绑定值,可以禁用:
参数嗅探是SQL Server创建
使用调用参数优化存储过程的计划
第一次执行存储过程时传递的
使用相同参数对同一存储过程的每次后续调用也将得到一个最优计划,而使用不同参数值的调用可能并不总是得到一个最优计划
运行速度减慢:
CREATE PROC [dbo].[DisplayBillingInfo]
@BeginDate DATETIME,
@EndDate DATETIME
AS
BEGIN
SELECT BillingDate, BillingAmt
FROM BillingInfo
WHERE BillingDate between @StartDate AND @StopDate;
END
快速运行(因为每次都必须计算新的执行计划):
情况是SQL Server optimizer无法重用缓存的计划并每次对其进行评估
这与您在重新编译时使用的相同:
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
谢谢@lad2025。您完全正确地理解了我必须做什么才能使查询在SQL Server 2012上快速运行。但为什么只在SQL server 2012上?为什么该过程在SQL server 2008上运行良好?@kudlur可能在SQL server 2008中缓存了最佳计划,并提供了与之配合良好的参数。您可以尝试使用不同的参数重新创建问题吗。另外,如果您正在测试clear buffer firstSQL server 2008 R2是生产版,并且到目前为止从未遇到过慢度问题。在SQL server 2012上,存储过程的第一次执行就出现了问题。删除和重新创建并没有解决问题。“重新编译”选项也不起作用。@kudlur TrySELECT。。。从…起选项(重新编译)
而不是使用“重新编译”
@kudlur的,如果它嗅探到的参数值与您正在使用的参数值相同(第一次运行),并且您仍然得到一个错误的计划,您可能需要更新统计信息。谢谢@lad2025。您完全正确地理解了我必须做什么才能使查询在SQL Server 2012上快速运行。但为什么只在SQL server 2012上?为什么该过程在SQL server 2008上运行良好?@kudlur可能在SQL server 2008中缓存了最佳计划,并提供了与之配合良好的参数。您可以尝试使用不同的参数重新创建问题吗。另外,如果您正在测试clear buffer firstSQL server 2008 R2是生产版,并且到目前为止从未遇到过慢度问题。在SQL server 2012上,存储过程的第一次执行就出现了问题。删除和重新创建并没有解决问题。“重新编译”选项也不起作用。@kudlur TrySELECT。。。从…起选项(重新编译)
而不是使用“重新编译”
@kudlur的,如果它嗅探的参数值与您正在执行的参数值相同(第一次运行),并且您仍然得到一个错误的计划,您可能需要更新统计信息。应该在DBA.se上,因为这不是编程问题。应该在DBA.se上,因为这不是编程问题。