Parameter Sniffing in SQL Server occurs when the query optimizer creates an execution plan for a stored procedure or query based on the parameter values used during the initial execution. This plan is then reused for subsequent executions, which can lead to suboptimal performance if the initial parameter values are not representative of later values.
When a query or stored procedure is
executed for the first time, SQL Server "sniffs" the parameter values
provided and generates an execution plan based on these specific values. This
plan is then stored in the plan cache and reused in subsequent executions to
save the overhead of re-creating a plan each time.
While parameter sniffing can
improve performance by allowing SQL Server to optimize the query based on the
actual data distribution for the provided parameters, it can lead to issues
when the parameters vary significantly across different executions. If a plan
optimized for one set of parameters is reused for a different set, it may not
perform optimally.
Symptoms of parameter sniffing can be
Ø The stored procedure performance execution performance shows inconsistency. It means that the procedure runs efficiently sometimes, but inefficiently at other times
Ø Sudden degradation of procedure performance
Ø If there is fixing in the procedure performance after updating the statistics
Ø If there is fixing in the procedure performance after recompiling the procedure statistics
Ø If it shows different performances for the same parameters in SSMS and application
Ø If the procedure query shows better performance than the stored procedure
See the example
We are
using the AdventureWorks2019 DB for demo.
Here we
are creating the sp for the demo
CREATE PROCEDURE P_getcustomershipdate (@Shipdate_start DATETIME, |
Now
creating a non-cluster index on the ship column for index seek.
create nonclustered index IX_salesOrderHeader_ship on sales.SalesOrderHeader (ShipDate) |
This table has 31465 records.
Let’s
run the sp with below parameters.
Turn on
the execution plan and running the first query.
exec P_getcustomershipdate '2011/07/07','2014/07/07' |
Executed
and return the 31286 records. See the execution plan.
Here we
are expecting that seek will happen but not here index scan happen because when
optimizer is creating the execution plan it look the statics and based on it
create the execution plan. In our case here we have requested more than 90% of
data due to that optimizer go with scan instead of index seek.
Let’s
run the second query
exec
P_getcustomershipdate '2011/06/07','2011/07/07' |
It
returns 184 records. See the execution plan.
Here it used the previous execution plan and for the 184 records it do the index scan.
Let’s
clear the execution plan and flip the execution of this sp and see.
DBCC
FREEPROCCACHE
Read more: DBCC FREEPROCCACHE
exec P_getcustomershipdate '2011/06/07','2011/07/07' |
See the execution plan
Here index seek happen.
Now running the second sp.
exec P_getcustomershipdate '2011/07/07','2014/07/07' |
See the execution plan
This
behavior of Sp execution is known as Parameter sniffing.
No comments:
Post a Comment
If you have any doubt, please let me know.