Introduction
Whenever a Stored Procedure or parameterized query is executed, the query optimizer tries to reuse the execution plan. If an execution plan already exists for a Stored Procedure or parameterized query in the cache then the query optimizer will blindly reuse it. If an execution plan is not present in the cache then the query optimizer creates a well-optimized execution plan based on input parameter values. The query optimizer will use the same execution plan for the next call of the Stored Procedure. This is known as parameter sniffing. Parameter sniffing is enabled by default in SQL Server. The cached execution plan may not be well-optimized for the new parameter, hence the second call of the query may be very slow.
The advantage of this behavior of the optimizer, is that the optimizer needs not re-create the execution plan to execute the same query multiple times. The optimizer will go and search the execution plan that is compiled earlier from the cache. This looks beneficial when good statistcs are maintained and typical parameters are used.
Parameter Sniffing Workaround
Disabling the parameter sniffing is helpful when there are several parameters in a Stored Procedure and there is also no favorite combination of parameters. If the value of parameters is not known at the time of compilation then there is nothing to be sniffed.
Using following, we may avoid the issue with parameter sniffing.
In this article I am using the same example from my previous article:
Parameter Sniffing in SQL Server
Use dummy variables that are not directly used as parameters
Use of a dummy variable that is not used as a parameter also ensures the stability of the execution plan.
CREATE PROCEDURE TestStoreProcedureNew
(
@CompanyId INT
)
AS
BEGIN
DECLARE @DummyCompanyId INT
SET @DummyCompanyId = @CompanyId
SELECT * FROM EmployeeMaster em
INNER JOIN EmployeeDetails ed ON em.DetailId = ed.EmployeeDetailId
WHERE em.CompanyId = @DummyCompanyId
END

Execute Stored Procedure using "WITH RECOMPILE" option
This solution enforces recompilation of the Stored Procedure on each run, so every time the optimizer creates a new execution plan for the current parameters.
EXEC TestStoreProcedureNew 1002 WITH RECOMPILE
--OR
CREATE PROCEDURE TestStoreProcedureWithRecompile
(
@CompanyId INT
)
WITH RECOMPILE
AS
BEGIN
SELECT * FROM EmployeeMaster em
INNER JOIN EmployeeDetails ed ON em.DetailId = ed.EmployeeDetailId
WHERE em.CompanyId = @CompanyId
END
Query hint RECOMPILE
SQL Server offers the new query hint RECOMPILE that forces query recompilation. This is a better way in which only a specific query is recompiled but in the above method entire the Stored Procedure is recompiled on every call. OPTIMIZE FOR in a query hint allows us to specify a constant that is used by the optimizer while optimizing the query.
CREATE PROCEDURE TestStoreProcedureQueryHint
(
@CompanyId INT
)
AS
BEGIN
SELECT * FROM EmployeeMaster em
INNER JOIN EmployeeDetails ed ON em.DetailId = ed.EmployeeDetailId
WHERE em.CompanyId = @CompanyId



Keyur PatelPosted Nov 18, 2013, 4:57 AM
Detail explanation on controlling parameter sniffing in Sql server. Good article.