/* ------------------------------ *\

    Copyright 2021 by Wingenious

   see README for license details

\* ------------------------------ */


------------------
Parameter Sniffing
------------------

Parameter Sniffing occurs when SQL Server uses the parameter value from a stored procedure call as information to generate an execution plan, which happens when there's no plan in the cache. A problem occurs when a cached execution plan works fine for the original parameter value, but not for the current parameter value. It happens when different parameter values result in very different quantities of rows. An execution plan designed for a small quantity of rows might be terribly inefficient for a large quantity of rows. An execution plan designed for a large quantity of rows might be terribly inefficient for a small quantity of rows. SQL Server uses the statistics, along with the parameter value, to generate an execution plan based on the quantity of rows it's expecting to handle. If the same plan is pulled from cache and used to handle a very different quantity of rows then there can be a parameter sniffing problem.

Please refer to the associated SQL file to see parameter sniffing in action. Execute the blocks of SQL code, one at a time, and observe what happens with execution plans.

There are several potential ways to deal with parameter sniffing issues. Here are some possible approaches:

    recompile at procedure level
    recompile at statement level
    assign parameter to local variable
    OPTIMIZE FOR @parameter = literal (or UNKNOWN)
    disable parameter sniffing for the database (database scoped configuration)
    use different stored procedures for different parameter values
    use plan guides

All of these approaches have drawbacks. Generally, they impose a modest performance loss for all/many executions in exchange for avoiding any enormous performance loss. There's no perfect solution.

The INCLUDE tool supports a different approach. It suggests potential extensions to indexes to make them covering indexes. The covering indexes provide a performance gain for all executions. It happens by using an index seek instead of an index seek with key lookup or a clustered index scan. The drawback is that covering indexes will consume more disk space. Some care must be taken to achieve a reasonable trade-off between performance and disk space. Adding one or two narrow columns to an index in exchange for better performance is probably a good trade-off. Adding a dozen wide columns to an index in exchange for better performance is probably a bad trade-off.


