sql-server

11 Пост

oracle

14 Пост

postgresql

13 Пост

my-sql

2 Пост

common-sql

3 Пост

News

5 Новости

Parameter Sniffing

Parameter Sniffing is a SQL Server behavior where, during query compilation, the optimizer uses the actual parameter value passed to a stored procedure or parameterized query to create an execution plan.

The generated execution plan is then stored in the plan cache and can be reused by subsequent executions with different parameter values.

This is normally beneficial because SQL Server can use the actual parameter value together with table statistics to create an efficient execution plan.

The problem appears when different parameter values have significantly different cardinalities.

For example:

@CustomerID = 1001  →          5 rows
@CustomerID = 1     →  1,000,000 rows

If the procedure is first compiled with:

@CustomerID = 1001

SQL Server may create a plan suitable for retrieving only a few rows, such as an Index Seek with Key Lookups.

That plan is cached.

Later, the same procedure may be executed with:

@CustomerID = 1

which returns 1,000,000 rows.

SQL Server may reuse the previously cached plan even though a completely different execution strategy would be more efficient for such a large number of rows.

The opposite situation is also possible: a plan compiled for a high-cardinality parameter can later be reused for a low-cardinality parameter.

Therefore, Parameter Sniffing itself is not a problem. It becomes a performance problem when a plan generated for one parameter value is reused for another parameter value with a substantially different data distribution or cardinality.

First parameter value
        ↓
SQL Server sniffs the value
        ↓
Optimizer creates a plan for that value
        ↓
Plan is cached
        ↓
Different parameter value
        ↓
Cached plan is reused
        ↓
Plan may no longer be efficient

Resolution

There is no single solution for every Parameter Sniffing problem. The appropriate approach depends on the query, data distribution, execution frequency, and SQL Server version.

Common solutions include:

  • OPTION (RECOMPILE) — generates a new execution plan for the current parameter value each time the statement executes.
  • WITH RECOMPILE — recompiles the stored procedure for each execution.
  • OPTIMIZE FOR — instructs SQL Server to optimize the query for a specified parameter value.
  • OPTIMIZE FOR UNKNOWN — prevents optimization for the currently sniffed parameter value and instead uses a more general statistical estimate.
  • Query Store hints / plan control — can influence or stabilize query behavior without changing application code.
  • Parameter Sensitive Plan (PSP) optimization — available in modern SQL Server versions and allows SQL Server to maintain multiple plan variants for different parameter-value ranges.

Each solution has advantages and disadvantages. For example, recompilation can produce a plan appropriate for the current parameter value, but frequent compilation also consumes CPU resources.

The correct solution should therefore be selected only after identifying how different parameter values affect the execution plan.

Parameter Sniffing Solutions — Advantages and Disadvantages

Solution Advantages Disadvantages Best Used When
OPTION (RECOMPILE) Creates a plan specifically for the current parameter value. Handles highly different cardinalities very well. Only recompiles the affected statement. Compilation occurs on every execution. Additional CPU overhead. The statement plan is not reused in the normal way. Parameter values have very different cardinalities and the query is expensive enough that getting the correct plan is more important than compilation cost.
WITH RECOMPILE Entire procedure is optimized for the current parameters on every execution. Simple to implement. Avoids reuse of an unsuitable cached procedure plan. Recompiles the whole procedure rather than only the problematic statement. Can cause unnecessary compilation overhead for procedures containing many statements. Most or all statements in a procedure depend strongly on the supplied parameters.
OPTIMIZE FOR Produces predictable optimization based on a chosen parameter value. No recompilation on every execution. Plan can still be cached and reused. The chosen value may not represent all executions. Data distribution can change over time. A plan good for the chosen value can still be poor for other values. One value or data distribution is representative of most executions.
OPTIMIZE FOR UNKNOWN Avoids creating the plan specifically for the parameter value that happens to trigger compilation. Produces more stable behavior when parameter values vary. Keeps plan reuse. Generic estimates may not be optimal for any particular value. Can still perform poorly when data is extremely skewed. A general-purpose plan performs acceptably across most parameter values.
Query Store Hints Can change query behavior without modifying application SQL. Useful for production systems where source code is difficult to change. Centrally manageable and removable. Requires Query Store and a supported SQL Server version/feature set. The underlying hint still has the advantages and disadvantages of the chosen strategy. Requires monitoring as workloads change. A production query needs tuning but application or stored-procedure code cannot easily be changed.
Parameter Sensitive Plan (PSP) SQL Server can maintain multiple plan variants for different parameter ranges. Preserves plan caching while accommodating different cardinalities. Avoids recompiling every execution. Requires supported SQL Server versions and compatibility settings. Not every parameter-sensitive query qualifies. SQL Server determines the ranges and variants automatically. Modern SQL Server environments where parameter values have significantly different cardinalities and multiple plans are beneficial.
sp_recompile Easy way to invalidate an existing cached plan and force compilation on the next execution. Useful for testing and diagnosis. Does not solve the underlying Parameter Sniffing problem. The next parameter becomes important for the new compilation, so the problem can return. Troubleshooting, testing, or intentionally forcing a one-time recompilation after relevant changes.

Quick Comparison

Solution Multiple Plans Recompile Every Execution Keeps Plan Reuse Handles Strong Data Skew
OPTION (RECOMPILE) Effectively yes, per execution ✅ ❌ ✅
WITH RECOMPILE Effectively yes, per execution ✅ ❌ ✅
OPTIMIZE FOR ❌ ❌ ✅ ⚠️ Depends on chosen value
OPTIMIZE FOR UNKNOWN ❌ ❌ ✅ ⚠️ Limited
Query Store Hints Depends on hint Depends on hint Depends on hint Depends on hint
PSP ✅ ❌ ✅ ✅
sp_recompile ❌ ❌* ✅ ❌