Reputation: 1213
I have a SQL Server stored procedure and it runs fine on SQL Server 2008 R2.
When I try to run it on SQL Server 2012, it takes very very long time to run.
But if I create local variables inside the stored procedure and copy the values of input parameters into those local variables and use them instead of input parameters, query runs and returns result faster than on SQL Server 2008 R2 database (please note both 2008 R2 and 2012 servers run on the same box).
Could you please shed some light on what is going on here?
Upvotes: 1
Views: 145
Reputation: 175616
By creating local variables and rebinding values you disable parameter sniffing:
Parameter sniffing is the process whereby SQL Server creates an optimal plan for a stored procedure by using the calling parameters that are passed the first time a stored procedure is executed
Every subsequent call to the same store procedure with the same parameters will also get an optimal plan, whereas calls with different parameter values may not always get an optimal plan
Run slows:
CREATE PROC [dbo].[DisplayBillingInfo]
@BeginDate DATETIME,
@EndDate DATETIME
AS
BEGIN
SELECT BillingDate, BillingAmt
FROM BillingInfo
WHERE BillingDate between @StartDate AND @StopDate;
END
Run fast (because it has to calculate new execution plan each time):
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
The case is SQL Server optimizer cannot reuse cached plan and evaluate it each time.
This is the same as you use 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
using query hint:
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
Upvotes: 7