24 Jun
2009

Repost: Watch out for SQL Server Parameter Sniffing

Category:UncategorizedTag: :

I posted on this about a year ago.  I am reposting this as a Public Service Announcement (otherwise known as a PSA).

Do you have a stored procedure where the amount of data returned can vary wildly depending on what parameters are passed in?  Does performance change dramatically depending on how much data is being returned?  You could be a victim of SQL Server Parameter sniffing.

Luckily there is an easy fix that doesn?t involve medication?but you might have to change some of your code, just a little bit.

Take your standard stored procedure:

   1: CREATE PROCEDURE GetUserData
   2:     @UserName nvarchar(20)
   3: AS
   4: BEGIN
   5:     SELECT DisplayName, FirstName, LastName 
   6:     FROM dbo.User
   7:     WHERE UserName = @UserName
   8: END

And make the following (highlighted) changes.

   1: CREATE PROCEDURE GetUserData
   2:     @UserName nvarchar(20)
   3: AS
   4: BEGIN
   5:     DECLARE @myUserName nvarchar(20)
   6:      SET @myUserName = @UserName
   7:  
   8:     SELECT DisplayName, FirstName, LastName 
   9:     FROM dbo.User
  10:     WHERE UserName = @myUserName
  11: END

Also note: if you read through the links of my previous post, you will see this issue affects more than just SQL Server.

4 thoughts on “Repost: Watch out for SQL Server Parameter Sniffing

  1. Chris, this is a great post. I would like to add one point. I have run into this issue many times at the company I work for. Where this usually becomes an issue is when you have an sp that looks like this:

    CREATE PROC spReturnUsers
    @UserName NVARCHAR(20),
    @FirstName NVARCHAR(20)
    AS
    BEGIN
    SELECT *
    FROM tbUsers
    WHERE (UserName = @UserName OR @Username IS NULL)
    AND (FirstName = @FirstName OR @FirstName IS NULL)
    END

    Now I will admit I do not have a great understanding of this so forgive me if I am wrong but what happens is this, during the execution of the above script it will scan the entire table for Username = @Username and then check if the @UserName is NULL. This is when you get the terrible response times. On other hand when it runs fast it is checking to see if the @UserName is NULL right away. I believe the reason why declaring the variables locally solves the problem is because SQL Server will then always check the IS NULL portion of each line first. Whereas, if it is not declared locally SQL Server is not smart enough to look at that first.

Comments are closed.