Parameter Sniffing is usually thought of as the bad guy, in association with a performance problem in your database. Contrary to the popular belief, Parameter Sniffing is usually the good guy, continuously working under the hood to help your database applications run faster. However, it can sometimes go wrong, causing severe performance degradation of your queries.
In this session we will discuss the workings of Parameter Sniffing and demonstrate how it helps improve the performance of your database applications. We will also explore how Parameter Sniffing can go wrong and its impact. Several ways to fix bad Parameter Sniffing will be demonstrated to help make an appropriate choice for your scenario.
1. UNDERSTANDING
PARAMETER SNIFFING
AND MAKING IT WORK FOR YOU
Sanil Mhatre, MCTS
Database Developer, Scottrade
Commentary and opinions expressed are those of the author/speaker and not necessarily those of Scottrade. Scottrade does not guarantee the accuracy of, or
endorse, the views or opinions of guest speaker, commentator, or author.
2. About Me
Database Developer
http://www.sqlwithsanil
@SQLSuperGuru
SQL Server Central
MSDN Forums
SQL Saturday #154 | St. Louis, MO | Sept 15th
3. Agenda
Understanding Parameter Sniffing
Query Optimizer
Procedure/Plan Cache
Recognize good parameter Sniffing
Recognize Bad Parameter Sniffing
Dealing with Bad Parameter Sniffing
6. Understanding Parameter
sniffing
Parameterization - Converting a SQL Statement
to a template
Auto Parameterization
Simple
Forced
Explicit Parameterization
Optimizer creates a reusable cached plan
Helps optimize similar queries with less overhead
7. Recognize good Parameter
sniffing
Query optimization is resource intensive
Optimizer uses statistics for decision making
Accuracy of the execution plan depends on;
Accuracy of statistics
Distribution of data
Working Example of parameter sniffing
Simple TSQL
Complex TSQL
8. Recognize Bad Parameter
Sniffing
Same Process but inaccurate plans
Still about statistics
Incomplete or stale statistics
Up to date statistics, but skewed data distribution
It might happen intermittently
Different inputs results in differing performance
Right plan is the one that’s best for majority of
your data
9. Dealing with Bad Parameter
Sniffing
OPTIMIZE FOR query hint
Value
UNKNOWN
RECOMPILE
Statement Level
Procedure Level
Local Variables
Plan Guides
Turn off Parameter Sniffing
10. OPTIMIZE FOR query hint
Value
Well known data
Stable distribution
Focused approach
Vulnerable to data changes over times
UNKNOWN (SQL Server 2008 & above)
Generic approach
Data is not well known
Data distribution is not stable
No Compile value
11. RECOMPILE
Statement or Procedure Level
Recompiles at each Run
New Execution plan at each Run
Works best when:
Data is not well known and/or extremely volatile
Generic plan is almost always sub-optimal
Custom plans needed for each parameter set
Recompiles can be expensive
Locking
12. Local Variables
Eliminates Parameters
Prevents Optimizer from “sniffing”
Optimizer will decide what's best for majority of
the data
Similar to OPTIMIZE FOR UNKNOWN
Produces Generic Plans
Useful when a specific value can’t be readily
determined
13. Plan Guides
Mechanism to apply query hints
Doesn’t require any TSQL code modification
3 types
Object – Stored procedures, triggers, functions
SQL – Ad hoc queries & batches
TEMPLATE – automatically parameterized
queries
Used when you can’t modify the code
Cumbersome to create and maintain
14. Turn off parameter sniffing
Vast majority of queries suffering
Very poor data distribution
Tried working on statistics & tuning queries
Recompiles are extremely expensive
Solution of the last resort & Extremely
Dangerous
It turns off good parameter sniffing as well
Must have up-to-date cumulative update
Setting traceflag 4136 to on/off
15. Summary
Parameter Sniffing
Query Optimizer
Procedure/Plan Cache
Good Vs Bad Parameter Sniffing
Options to fix Bad parameter Sniffing
16. Resources
SQL Server MVP Deep Dives – Grant
Fritchey’s Chapter on Parameter Sniffing.
Inside the SQL Server Query Optimizer –
Benjamin Nevarez.
Query Plan Usage – Bill Graziano’s session
material from http://www.scalesql.com/default.aspx
‘Parameterized Queries’ – Database Journal
article by Gregory A. Larsen
‘The SQL Server Query Optimizer’ – simple-
talk article by Benjamin Nevarez
17. Questions ?
Commentary and opinions expressed are those of the author/speaker and not necessarily those of Scottrade. Scottrade does not guarantee the accuracy of, or
endorse, the views or opinions of guest speaker, commentator, or author.
Editor's Notes
High Level Overview of The SQL Server Query Optimizer
The SQL Server Query Optimizer is a cost based optimizer
It analyzes a number of candidate execution plans for a given query
It Estimates the cost of each of these plans
It selects the plan with the lowest cost of the choices considered
The Query optimizer cannot really consider every possible plan for every query
It does a cost based balancing act – considering both the cost of finding potential plans and the costs of the plans themselves
The optimizer is the component that has the biggest impact on the performance of your database
http://www.simple-talk.com/sql/sql-training/the-sql-server-query-optimizer/
SQL Server decides the appropriate allocation of memory to the Plan Cache from the Buffer Pool ( Also known as the procedure cache in older versions of SQL Server)
Four types of object are stored in the Plan Cache: Object Plans, SQL Plans, Bound Trees and Extended Stored Procedures
Plans are cached for possible reuse opportunities
If a query plan is not cached, its reuse opportunity is zero. Such a plan will be compiled & optimized every time it is executed, potentially resulting in poor performance
If a valid plan is available in the plan cache, it could be reused, skipping the optimization process
Thus the associated cost of this step in teams of optimization time, CPU resources, etc can be avoided
Sizing of Plan Cache :
2008 & 2005 Sp2 - 75% of visible target memory from 0-4GB + 10% of visible target memory from 4Gb-64GB + 5% of visible target memory > 64GB
2005 RTM & 2005 SP1 - 75% of visible target memory from 0-8GB + 50% of visible target memory from 8Gb-64GB + 25% of visible target memory > 64GB
2000 - 4GB upper cap on the plan cache
SQL Server Instance Memory can be set/changed using the “Memory” Tab under Properties of the Instance
http://msdn.microsoft.com/en-us/library/ee343986(v=sql.100).aspx
Parameterization of a query means replacing the literals in the filter of the query with parameters
It Converts the SQL Statement to a template so that the Query Plan can be re-used
Stored Procedures are always parameterized for their parameters
By default, query optimizer will automatically do this for you
Simple parameterization is the default
Tells sql server to parameterize simple TSQL statements ( few or no joins , simple filters, no functions & aggregations)
http://www.sqlteam.com/article/introduction-to-parameterization-in-sql-server
Forced parameterization tells SQL server to parameterize all TSQL statements running in your database, not just simple TSQL
You can change between simple & forced Parameterization options at the database level by going into Database properties > Options > Miscellaneous > Parameterization
You can also explicitly parameterize your queries by writing them in a specific way and using sp_executesql system stored procedure to execute them
Parameterization helps reuse of cached execution plan for similar queries
Even the slightest change in the text will prevent SQL Server from reusing the query plans
SET Options will also affect the reuse of execution plans
http://www.benjaminnevarez.com/2011/09/parameter-sniffing-and-plan-reuse-affecting-set-options/
Query optimization is a resource intensive process and this mechanism helps save valuable resources and time
Demo Script 0
Discuss how query optimization is expensive (CPU resources, optimization time)
Query optimizer will use statics to make decisions such as if an index should be used, which index should be used – scan or seek etc
So statistic play a vital role in creation of the execution plan
When proc is executed for first time, the value of the parameter is passed to the optimizer, which uses the value to search the statistics
This generates more accurate execution plans
This process of using the value from the parameter is known as parameter sniffing
demo script 0
Discuss how a simple query is parameterized by SQL Server
Discuss how using local variable prevents parameterization
Discuss how stored procedures always reuse execution plans but using local variables prevents parameterization
Discuss how parameter sniffing was working in your benefit on all of the above cases.
Demo script 1
Different plans are optimal for different inputs
Parameter sniffing will cause optimizer to create a plan that is optimal for the input during first execution of that proc
This plan is cached for future use
The cached and reused plan may not be optimal for your particular input
using local variables forces the optimizer to not consider the input value when coming up with the execution plan
this will force the optimizer to generate the execution plan that is best for majority of your data
When it has been confirmed that Parameter Sniffing is not working in your favor in a given scenario, there are several techniques to help produce an optimal execution plan
The technique to choose will depend on your specific situation
Is your data distribution consistent ?
Do you have volatile & widely distributed data ?
Do you need a generic plan that works well in most cases ?
Do you need to create a new plan each time the stored proc is called ?
Give a disclaimer – test thoroughly before choosing and implementing a strategy for your particular situation
Demo script 2
These optimizer hints have to be used with caution because you are overwriting the optimizer’s decisions
Optimize for Value hint is a very narrow & focused approach that will produce for results for the given value
Performance might suffer for other inputs depending on the data distribution
Optimize for unknown hint was introduced in SQL Server 2008 & is same as using local variables
Optimizer will generate a plan that it thinks is best for majority of the data it has sampled
Statement Level – effective on one statement in a given block
procedure Level – if all statements in the proc suffer from bad parameter sniffing , use this instead of multiple statement level
This will recompile the stored proc each time it is called
Execution plan will be different for each parameter
Compile value in the parameter list will be different each time as well
This approach works best when
Your data and its distribution is not well known
your data is extremely volatile
most of your data will not benefit from a single generic execution plan
custom plan is needed for each parameter set
However, this solution can introduce severe problems of its own, depending on the complexity of the statement or procedure
compiling the execution plan for each call can be expensive
not using cache will incur the cost of query optimization at each run
recompiles will lock the procedure to other users until recompile completes
could lead to sever issues for frequently called stored proc
Severe CPU Spikes due to excessive recompiles
using local variables blinds the optimizer to from using specific “sniffed” values
optimizer will scan statistics and used sampled value
this will produce generic plan
this is similar to using the OPTIMIZE FOR UNKNOWN Query hint
Generic plans can be good in some situations – where data distribution is consistent but a specific value can’t be readily determined
however, if your data set demands custom plans for specific values, this approach will produce sub-optimal plans
They are a mechanism used to apply hints to a query without doing any TSQL code modification
Very useful when you have third party or vendor TSQL code that cannot be modified
3 types of plan guides
Object – An OBJECT plan guide matches queries that execute in the context of Transact-SQL stored procedures, scalar user-defined functions, multi-statement table-valued user-defined functions, and DML triggers.
SQL – An SQL plan guide matches queries that execute in the context of stand-alone Transact-SQL statements and batches that are not part of a database object. SQL-based plan guides can also be used to match queries that parameterize to a specified form
TEMPLATE – A TEMPLATE plan guide matches stand-alone queries that parameterize to a specified form. These plan guides are used to override the current PARAMETERIZATION database SET option of a database for a class of queries.
Best suited to situations where you cannot edit the TSQL code
you can use any of the hints we discussed earlier in the plan guide
text has to be exact
Show plan guide creation demo
Show the created guide in object explorer
Show execution plan SELECT properties and use of the plan guide
Vast Majority of your queries are suffering from bad parameter sniffing
All of the solutions discussed previously have failed or cannot be used
Your data is extremely skewed
you have tried creating & updating statics and various query tuning techniques
Recompiles are turning out to be extremely
you have exhausted every other option and have determined that turning off parameter sniffing is the only possible solution
you have confirmed that queries that were being benefited by good parameter sniffing are not going to be a huge performance drag
its Server level Setting, Turns it off for all databases on the given server
Its extremely dangerous as it turns off good parameter sniffing as well
all queries will run as if they have OPTIMIZE for unknown hint
you must have installed the cumulative update as described here - http://support.microsoft.com/kb/980653
SQL Server 2008 R2 Cumulative Update 2, SQL Server 2008 SP1 Cumulative Update 7 and SQL Server 2005 SP3 Cumulative Update 9 introduce trace flag 4136 that can be used to disable the "parameter sniffing" process
once that’s installed, turn on the trace flag 4136 to switch off parameter sniffing
it will stay off, until the turned back on using the trace flag.
Queries that meet any of the following conditions still undergo parameter sniffing even if the trace flag is set.
The parameter is specified by using the "optimize for (@p = <value>)" query hint.
The query uses the "option(recompile)" query hint.
The query is a part of a stored procedure that uses the "with recompile" option.
last resort solution for a poorly designed third party system, where creating hundreds of plan guides is not an option – or all code is generated by an ORM engine, you can’t edit it or affect how its put together.