SQLSERVER parameter sniffing

Source: Internet
Author: User
What is SQLSERVER parameter sniffing? When you hear this word, you may feel that it is related to hackers. Use a tool to sniff the parameter and then intercept the parameter, and remove the pants o (_) o. In fact, I think everyone is too sensitive. In fact, this article has nothing to do with database security. In fact, it is related to database performance tuning. I believe everyone has a forum on SQLSERVER.

What is SQLSERVER parameter sniffing? When you hear this word, you may feel that it is related to hackers. Use a tool to sniff the parameter and then intercept the parameter, and remove the pants o (_) o. In fact, I think everyone is too sensitive. In fact, this article has nothing to do with database security. In fact, it is related to database performance tuning. I believe everyone has a forum on SQLSERVER.

SQLSERVER parameter sniffing

Everyone heard"Sniffing"The term should be related to hackers. Use a tool to sniff the parameters and intercept the parameter, and then take a look at it.

In fact, I think everyone is too sensitive. In fact, this article has nothing to do with database security. It is actually related to database performance tuning.

I believe that many of you may have seen the Forum"Parameter sniffing"

Three posts are about parameter sniffing.

Http://social.msdn.microsoft.com/Forums/zh-CN/sqlserverzhchs/thread/caccb7f3-8366-4954-8f8a-145eb6bca9dd

Http://msdn.microsoft.com/zh-cn/magazine/ee236412.aspx

Http://social.msdn.microsoft.com/Forums/zh-CN/sqlserverzhchs/thread/bfbe54de-ac00-49e9-a83b-f97a60bf74ef

Below I will provide a backup file for the test database, which contains some tables and some test data, you can download it, because the test tables I use below are all in this database

You only need to restore the database. The database is in SQL2005 and the database name is AdventureWorks.

The following uses three tables with indexes:

[Production]. [Product]
[SalesOrderHeader_test]
[SalesOrderDetail_test]

Database download link:AdventureWorks_Full_backup_2013-3-4.bak

In fact, the common explanation of parameter sniffing is that SQL Server cannot sniff specific parameters.

Therefore, he cannot select the most suitable execution plan to execute your query, so parameter sniffing is a bad phenomenon.

To learn more about parameter sniffing, You can first create the following two stored procedures:

Stored Procedure 1:

 1 USE [AdventureWorks] 2 GO 3 DROP PROC Sniff 4 GO 5 CREATE PROC Sniff(@i INT) 6 AS 7 SELECT COUNT(b.[SalesOrderID]),SUM(p.[Weight]) 8 FROM [dbo].[SalesOrderHeader_test] a 9 INNER JOIN [dbo].[SalesOrderDetail_test] b10 ON a.[SalesOrderID]=b.[SalesOrderID]11 INNER JOIN [Production].[Product] p12 ON b.[ProductID]=p.[ProductID]13 WHERE a.[SalesOrderID]=@i14 GO

Stored Procedure 2:

 1 USE [AdventureWorks] 2 GO 3 DROP PROC Sniff2 4 GO 5 CREATE PROC Sniff2(@i INT) 6 AS 7 DECLARE @j INT 8 SET @j=@i 9 SELECT COUNT(b.[SalesOrderID]),SUM(p.[Weight])10 FROM [dbo].[SalesOrderHeader_test] a11 INNER JOIN [dbo].[SalesOrderDetail_test] b12 ON a.[SalesOrderID]=b.[SalesOrderID]13 INNER JOIN [Production].[Product] p14 ON b.[ProductID]=p.[ProductID]15 WHERE a.[SalesOrderID]=@j16 GO

Then perform the following two tests:

Test 1:

1 -- Test 1: 2 USE [AdventureWorks] 3 GO 4 DBCC freeproccache 5 GO 6 EXEC [dbo]. [Sniff] @ I = 500000 -- int 7 -- compile, insert an execution plan using the nested loops join 8 GO 9 10 EXEC [dbo]. [Sniff] @ I = 75124 -- int11 -- execution plan reuse occurs, reuse the preceding execution plan of nested loops 12 GO

Test 2:

1 -- Test 2: 2 3 USE [AdventureWorks] 4 GO 5 DBCC freeproccache 6 GO 7 set statistics profile on 8 EXEC [dbo]. [Sniff] @ I = 75124 -- int 9 -- compile, insert an execution plan using hash match join 10 GO11 12 EXEC [dbo]. [Sniff] @ I = 50000 -- int13 -- execution plan reuse occurs, reuse the preceding hash match execution plan 14 GO

From the two tests above, we can clearly see the side effects of execution plan reuse.

Because the data distribution is very different, parameters 50000 and 75124 only have good performance for self-generated execution plans,

If the execution plan generated by the other party is used, the performance will decrease. The result set returned by parameter 50000 is small,

Therefore, the performance decline is not very serious. When the result set returned by parameter 75124 is large, the performance decreases significantly. The difference between the two execution plans is nearly 10 times.

SQSERVERL has a proprietary term called "parameter sniffing" for this sort of denial of service caused by reuse of execution plans generated by others"

The statement execution plan is very sensitive to variable values, which leads to performance problems when reusing the execution plan.

"

SQLSERVER cannot sniff the specific parameters with the nose, so it cannot select the most appropriate execution plan to execute your query.

"

Influence of local variables

What if a local variable is used for a stored procedure with a parameter sniffing problem?

See Test 3 below. When different variable values are used this time, the execution plan cache is cleared to force its re-compilation.

1 -- first 2 USE [AdventureWorks] 3 GO4 DBCC freeproccache5 GO6 set statistics time ON7 set statistics profile ON8 EXEC [dbo]. [Sniff] @ I = 50000 -- int9 GO

1 -- 2 USE [AdventureWorks] 3 GO4 DBCC freeproccache5 GO6 set statistics time ON7 set statistics profile ON8 EXEC [dbo]. [Sniff] @ I = 75124 -- int9 GO

1 -- 2 USE [AdventureWorks] 3 GO4 DBCC freeproccache5 GO6 set statistics time ON7 set statistics profile ON8 EXEC [dbo]. [Sniff2] @ I = 50000 -- int9 GO

1 -- fourth 2 USE [AdventureWorks] 3 GO4 DBCC freeproccache5 GO6 set statistics time ON7 set statistics profile ON8 EXEC [dbo]. [Sniff2] @ I = 75124 -- int9 GO

View their execution plan:


For the first and second sentences, because SQL knows the value of the variable during compilation, It is very accurate when doing EstimateRows and selects the execution plan most suitable for them.

However, for the third and fourth sentences, SQLSERVER does not know the value of @ j. Therefore, no matter what the value of @ I is during EstimateRows,

All prediction results are the same as those of @ j. So the two execution plans are exactly the same (bothHash Match).

Parameter sniffing Solution

The frequency of parameter sniffing problems is not high. It only occurs when the data distribution in some tables is uneven or the parameter values brought by the user are uneven.

I will not elaborate on it because of the length, but I will just make some Induction

(1) run dynamic SQL statements in exec () Mode

If you do not directly run the statement in the stored procedure, but put the statement with a variable, generate a string, and then run the exec () command as a dynamic statement,

Then, the SQL statement is compiled when the statement is run.

At this time, SQL knows the value of the variable and generates an optimized execution plan to bypass parameter sniffing.

1 -- for example, the previous Stored Procedure Sniff can be changed to 2 USE [AdventureWorks] 3 GO 4 drop proc NOSniff 5 GO 6 create proc NOSniff (@ I INT) 7 AS 8 DECLARE @ cmd VARCHAR (1000) 9 SET @ cmd = 'select COUNT (B. [SalesOrderID]), SUM (p. [Weight]) 10 FROM [dbo]. [SalesOrderHeader_test] a11 inner join [dbo]. [SalesOrderDetail_test] b12 ON. [SalesOrderID] = B. [SalesOrderID] 13 inner join [Production]. [Product] p14 ON B. [ProductID] = p. [ProductID] 15 WHERE. [SalesOrderID] = '16 EXEC (@ cmd + @ I) 17 GO

(2) Use the local variable

(3) Use query hint in the statement to specify the execution plan

At the end of the select, insert, update, and delete statements, you can add an "option ( ) "Clause

Provides guidance on the execution plan to be generated by SQLSERVER. After the DBA knows the problem, it can be guided by hint.

SQL generates a safer execution plan with no variable values.

 1 USE [AdventureWorks] 2 GO 3 DROP PROC NoSniff_QueryHint_Recompile 4 GO 5 CREATE PROC NoSniff_QueryHint_Recompile(@i INT)  6 AS 7 SELECT COUNT(b.[SalesOrderID]),SUM(p.[Weight]) 8 FROM [dbo].[SalesOrderHeader_test] a 9 INNER JOIN [dbo].[SalesOrderDetail_test] b10 ON a.[SalesOrderID]=b.[SalesOrderID]11 INNER JOIN [Production].[Product] p12 ON b.[ProductID]=p.[ProductID]13 WHERE a.[SalesOrderID]=@i14 OPTION(RECOMPILE)15 GO

(4) Plan Guide

The following method can be used to solve the sniffing problem in the stored procedure "Sniff" with the parameter sniffing problem.

 1 USE [AdventureWorks] 2 GO 3 EXEC [sys].[sp_create_plan_guide] 4 @name=N'Guide1', 5 @stmt=N'SELECT COUNT(b.[SalesOrderID]),SUM(p.[Weight]) 6 FROM [dbo].[SalesOrderHeader_test] a 7 INNER JOIN [dbo].[SalesOrderDetail_test] b 8 ON a.[SalesOrderID]=b.[SalesOrderID] 9 INNER JOIN [Production].[Product] p10 ON b.[ProductID]=p.[ProductID]11 WHERE a.[SalesOrderID]=@i',12 @type=N'OBJECT',13 @module_or_batch=N'Sniff',14 @params=NULL,15 @hints=N'option(optimize for(@i=75124))';16 GO

For Plan Guide, it can also be used in general statement optimization.

I finally got it done. It took a long time to test the data ~~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.