Repost: Watch out for SQL Server Parameter Sniffing

June 24th, 2009

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.

Chris Brandsma

  • http://www.aaronkjackson.com Aaron

    Chris, thanks for the post. This solved a problem I had with a report. Strange fix indeed.

  • http://www.alvinashcraft.com/2009/06/25/dew-drop-june-25-2009/ Dew Drop – June 25, 2009 | Alvin Ashcraft’s Morning Dew

    [...] Repost: Watch out for SQL Server Parameter Sniffing (Chris Brandsma) [...]

  • Ben

    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.

  • Sreeni

    Yes, it really help me to trouble shoot the time taking process in SSRS reports.

blog comments powered by Disqus