Monday 13 August 2012

SQL Parameter sniffing

At work we were having a problem with a few stored procedures that seemed to stop working randomly for some queries using SQL Server 2005. The stored procedure work correctly with one set of parameters, while with another set would timeout and fail.

The initial way that we bypassed this problem was that when this circumstance was found, we would drop and recreate the stored procedure and this seemed to fix it. As you can imagine it wasn't an ideal situation for an enterprise application because the problem would need to be found and reported before we would even know it existed but we struggled to find any proposed solutions to the problem.

After much investigation it was suggested that this could be caused by parameter sniffing. SQL Server does this by tracking what happens to the parameters passed into the stored procedure when creating the stored procedure and working out the execution plan. So the execution plan generated by SQL server was good most of the time but the plan would contain situations where the procedure would fail.

Below is a sample stored procedure that allows parameter sniffing. This is not one of the stored procedures that did have the problem, but a stored procedure where parameter sniffing occurs:

CREATE PROCEDURE Customer_Search
 @FirstName varchar(100),
 @LastName varchar(100)
AS
BEGIN

 SELECT 
  CustomerID,
  Firstname,
  Lastname,
  Username,
  Email
 FROM
  Customer
 WHERE
  Firstname LIKE ('%' + @FirstName + '%') AND
  LastName LIKE ('%' + @LastName + '%')
END
GO

With the following addition of two variables it prevents SQL Server from having the ability to perform parameter sniffing:

CREATE PROCEDURE Customer_Search
 @FirstName varchar(100),
 @LastName varchar(100)
AS
BEGIN
 -- Variables added to prevent problems that were occuring with parameter sniffing
 DECLARE 
  @FName VARCHAR(100),
  @LName VARCHAR(100)
   
 SELECT
  @FName = @FirstName,
  @LName = @LastName

 SELECT 
  CustomerID,
  Firstname,
  Lastname,
  Username,
  Email
 FROM
  Customer
 WHERE
  Firstname LIKE ('%' + @FName + '%') AND
  LastName LIKE ('%' + @LName + '%')
END
GO

By implementing the small change demonstrated above on a couple of troublesome stored procedures, this fixed our problem with our stored procedures randomly not working with certain parameters. This proved that the problem was caused by parameter sniffing and left me wondering how many other people are out there with the same problem.

3 comments:

  1. Yeah! That fixed my problem - the old parameter sniffing conundrum - I hate when that happens.

    Thanks for posting your experience!

    I have deadline for getting this code into a test environment tomorrow and this parameter sniffling has been eluding my grasp.

    Thank You!

    Stever

    ReplyDelete
    Replies
    1. Thanks for the feedback Steve, I am glad that it has helped someone.

      Good luck with the deadline!

      Delete