Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

PL/SQL & T-SQL (Oracle and SQL Server)  Module 7 – Execution plans and performance in SQL Server

Parameter sniffing, PSP and Query Store

See why one cached plan fits only some parameter values, reproduce parameter sniffing on skewed data, and fix it with PSP, hints and Query Store.

  • Advanced
  • 15 minutes
  • Examples run with oracle-free 23.26.3.0.0, mssql 17.0.5005.3, Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot
Free core, Pro depth: 5 of 15 minutes free
Free: One cached plan is built for the first value it sees · Whichever call comes first decides what the second one costs · Eight ways to stop one plan from serving every value · Query Store records every plan, and PSP lets one statement keep several. With a pass: 2 in-depth parts and 3 interview answers, about 10 minutes.

What you will learn

  • Explain parameter sniffing and reproduce it on skewed data with a model and a script
  • Apply a fix for a sniffed plan from OPTION (RECOMPILE), OPTIMIZE FOR, Query Store hints and plan forcing
  • Describe parameter sensitive plan optimization and optional parameter plan optimization
  • Find regressed queries in Query Store and compare their plans by logical reads

Before you start

What you’ll learn · Before you start

What you will learn

  • Explain parameter sniffing and reproduce it on skewed data with a model and a script
  • Apply a fix for a sniffed plan from OPTION (RECOMPILE), OPTIMIZE FOR, Query Store hints and plan forcing
  • Describe parameter sensitive plan optimization and optional parameter plan optimization
  • Find regressed queries in Query Store and compare their plans by logical reads

Before you start

On this page

In the page-count model of this lesson, one procedure reads 1,695 pages for the 99,000 ‘shipped’ orders of a 100,000-row table when it gets the plan built for them, and 297,418 pages when it reuses the plan built for the 10 ‘new’ orders: about 175 times as many. The plan, not the data, made the call expensive.

This is parameter sniffing: SQL Server reads the parameter values of the first call while it compiles a procedure or parameterized query, so the cached plan fits those values and may fit others poorly.: SQL Server reads the parameter values of the first call while it compiles, and the plan cache keeps that plan for every later call. parameter sensitive plan optimization: PSP optimization, from compatibility level 160: one parameterized statement can keep a dispatcher plan and several query variants, each with its own plan, chosen by the rows a value matches. optimization lets one statement keep several plans, and Query Store: A feature of each database that records queries, their execution plans and runtime statistics per time interval, so plan changes can be found and compared. records each plan with its reads, so a regression can be found and fixed without editing the code.

One cached plan is built for the first value it sees

A stored procedure’s plan goes into the plan cache: The memory area where SQL Server keeps compiled execution plans, so later calls of the same procedure or statement can reuse a plan instead of compiling again. the first time it compiles. While compiling, the optimizer reads each parameter’s value and estimates from the statistics: What SQL Server records about the values in a column or index, such as how many rows hold each range of values, so the optimizer can estimate how many rows a step of a query returns. More in “T-SQL temporary tables: #local and ##global” how many rows match. Microsoft calls this parameter sensitivity, also known as parameter sniffing, and applies it to stored procedures, sp_executesql and prepared queries. It usually helps. The trouble starts when values differ a lot. In the lab table status = N'new' matches 10 rows and status = N'shipped' matches 99,000, and the first call decides the plan until it leaves the cache or is recompiled:

Interactive · message by message Two calls, one cached plan Step through two calls of the same procedure and see which call decides the plan.
Two calls, one cached plan, step 5 of 5. Messages so far: Application to SQL Server: status = 'new'; SQL Server to Plan cache: store the plan; Application to SQL Server: status = 'shipped'; Plan cache to SQL Server: reuse the plan.Applicationcalls the procedureSQL Serverreuses, no compilePlan cacheseek + lookupsstatus = 'new'store the planstatus = 'shipped'reuse the plan297,418 reads in the model

The drawing shows the whole scene; its 5 steps are listed below.

Every step as text
  1. Call 1 asks for 'new'. The application runs the procedure with the status new, 10 of the 100,000 orders. Nothing is in the plan cache for the procedure yet.
  2. SQL Server sniffs the value. The optimizer reads the parameter value while it compiles and estimates 10 rows. In the model a seek on the status index plus 10 key lookups is cheapest, 33 reads against 1,695 for a scan.
  3. The plan is cached. The compiled plan, a seek with key lookups, is stored in the plan cache. The cache keeps the plan, not the value it was compiled for.
  4. Call 2 asks for 'shipped'. The application runs the same procedure with the status shipped, 99,000 of the 100,000 orders. The text of the procedure is the same, so SQL Server looks for its plan in the cache.
  5. The cached plan is reused. The cache has a plan, so nothing is compiled. The seek plan runs for 99,000 rows with one key lookup each, 297,418 reads in the model, while a scan would need 1,695.

Key idea

A cached plan is right for the value it was compiled with and a guess for every other value.

Checkpoint

Check: One cached plan, built for the first value

  1. Question 1 of 2 A procedure was first called with a status that matches 10 rows, and SQL Server compiled a seek plan. A second call asks for a status that matches 99,000 rows. What does SQL Server do?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: It reuses the cached plan and compiles nothing

    The cached plan runs for 99,000 rows with one key lookup each. It is not wrong for the first call, only a poor guess for the second.

  2. Question 2 of 2 No recompile happens between calls. Which call decides the plan that all later calls of a procedure use?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The first call after the plan was compiled

    After a restart, a plan leaving the cache or a recompile, the next call decides again.

Whichever call comes first decides what the second one costs

The model computes the data pages of a scan and the reads of a key lookup for the lab table from Microsoft’s index sizing formulas, with the same functions as the lesson on reading execution plans, and lets the optimizer pick the plan with the fewest expected logical reads: The number of 8 KB pages a statement read from SQL Server's data cache, reported per table by SET STATISTICS IO; pages read from disk are counted separately as physical reads. More in “T-SQL cursors and set-based rewrites”. Its numbers are estimates, not measurements of a server. Press Edit and set FIRST and SECOND to "cancelled" and "paid":

Two plans, two orders: the reads of each call Python · model/sniffing_model.py
"""Parameter sniffing on dbo.orders_big: a model of the page reads of the two plans a procedure can cache.

The table is the lab table of the tsql-performance module: 100,000 rows, a clustered primary key on
order_id and an index on status. The page counts come from Microsoft's index sizing formulas (the
same functions as plan_cost.py of the lesson on reading execution plans, so both print the same
numbers). The model assumes the optimizer picks the plan with the fewest logical reads it expects;
real SQL Server also weighs CPU, parallelism and random against sequential I/O, so these are the
model's estimates, not measurements. Edit FIRST and SECOND to try other calls.
"""

import math

FIRST, SECOND = "new", "shipped"  # the status values of two calls; the model runs both orders
ROWS = {"new": 10, "cancelled": 90, "paid": 900, "shipped": 99_000}
N = sum(ROWS.values())

# --- page counts from the sizing formulas (average lengths of the variable columns, full pages) ---
row_size = 20 + (2 + 3 * 2 + (14 + 6 + 80)) + (2 + (7 + 7) // 8) + 4
rows_per_page = 8096 // (row_size + 2)
leaf_pages = math.ceil(N / rows_per_page)  # a clustered index scan reads every one of them
ci_rows = 8096 // (4 + 2 + 1 + 6 + 2)
ci_levels = math.ceil(1 + math.log(leaf_pages / ci_rows, ci_rows))  # levels above the leaf level
nc_row = (2 + 2 + 14) + (2 + (1 + 7) // 8) + 1 + 6 + 4
nc_rows = 8096 // (nc_row + 2)
nc_pages = math.ceil(N / nc_rows)
nc_levels = math.ceil(1 + math.log(nc_pages / nc_rows, nc_rows))


def seek_lookup(k):  # seek on ix_orders_big_status, then one clustered lookup per row
    return nc_levels + max(1, math.ceil(k / nc_rows)) + k * (ci_levels + 1)


def scan(k):  # clustered index scan: every data page, whatever k is
    return leaf_pages


PLANS = {"seek+lookup": seek_lookup, "scan": scan}


def best(k):
    """The plan with the fewest expected reads for k rows."""
    return min(PLANS, key=lambda plan: PLANS[plan](k))


print(f"dbo.orders_big: {N:,} rows, {leaf_pages:,} data pages; a key lookup costs {ci_levels + 1} reads")
print(f"{'status':<10}{'rows':>7}{'seek+lookup':>13}{'scan':>7}   best plan")
for name, k in ROWS.items():
    print(f"{name:<10}{k:>7,}{seek_lookup(k):>13,}{scan(k):>7,}   {best(k)}")
tip = next(k for k in range(1, N) if seek_lookup(k) > scan(k))
print(f"Lookups cost more than the scan from {tip} rows on.")
print()
print("Call 1 compiles for its own value; call 2 reuses that plan from the cache.")
for first, second in ((FIRST, SECOND), (SECOND, FIRST)):
    cached = best(ROWS[first])
    r1, r2 = PLANS[cached](ROWS[first]), PLANS[cached](ROWS[second])
    ideal = PLANS[best(ROWS[second])](ROWS[second])
    print(f"{first} then {second}: cached plan {cached}; reads {r1:,} then {r2:,}; call 2 needs {ideal:,} at best")

Output

dbo.orders_big: 100,000 rows, 1,695 data pages; a key lookup costs 3 reads
status       rows  seek+lookup   scan   best plan
new            10           33  1,695   seek+lookup
cancelled      90          273  1,695   seek+lookup
paid          900        2,706  1,695   scan
shipped    99,000      297,418  1,695   scan
Lookups cost more than the scan from 564 rows on.

Call 1 compiles for its own value; call 2 reuses that plan from the cache.
new then shipped: cached plan seek+lookup; reads 33 then 297,418; call 2 needs 1,695 at best
shipped then new: cached plan scan; reads 1,695 then 1,695; call 2 needs 33 at best

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 sniffing_model.py

Key lookups cost more than the scan from 564 rows on. In the order new, shipped, the second call reads 297,418 pages where 1,695 would do; in the reverse order it reads 1,695 where 33 would do, about 51 times as many.

Checkpoint

Check: The reads of the two plans, in both orders

  1. Question 1 of 2 After a recompile the procedure gets 'shipped' (99,000 rows) first and 'new' (10 rows) second. What does the model say the second call reads?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: 1,695 pages, the cached scan, where 33 would do

    The other order is the unlucky one: the seek plan reused for 99,000 rows reads 297,418 pages.

  2. Question 2 of 2 From how many rows on does the model say a seek with key lookups costs more reads than the scan?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 564 rows

    The model prints it under the table: 564 rows, where the lookups reach 1,697 reads against the scan's 1,695.

Eight ways to stop one plan from serving every value

Each fix gives every value its own plan, gives all values one acceptable plan, or removes the lookups that made the plans differ:

Fix What it does
Covering index and statistics A covering index holds every column the query reads, so no lookups remain; current statistics keep estimates honest.
OPTION (RECOMPILE) Compiles the statement on every call with that call’s values and discards the plan afterwards.
OPTIMIZE FOR a value Compiles as if the parameter held a value you choose, whatever the call brings.
OPTIMIZE FOR UNKNOWN and local variables Both estimate from the column’s average density instead of a sniffed value, so every call gets one plan.
PSP optimization From compatibility level 160, one dispatcher plan can send each call to a query variant chosen by the rows its value matches.
optional parameter plan optimization: OPPO, from compatibility level 170: a search such as column = @p OR @p IS NULL can get separate query variants for a NULL parameter and for a value. From compatibility level 170, a search like column = @p OR @p IS NULL gets one variant for NULL and one for a value.
Query Store hint: A query hint attached to a query by its query_id in Query Store, so it applies without editing the code; available from SQL Server 2022. Attach a hint such as RECOMPILE to a query by its query_id, without editing the code, from SQL Server 2022.
plan forcing: Pinning a plan that Query Store recorded for a query_id, so the optimizer tries to use that plan whenever the query compiles. Pins a plan that Query Store recorded for a query_id, so the optimizer tries to use it at every compile.

Statistics and indexes come first, since Microsoft advises completing them before any hint.

Checkpoint

Check: The eight fixes, by name

  1. Question 1 of 2 Which fix compiles the statement again on every call and discards the plan after the call?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: OPTION (RECOMPILE)

    The price of RECOMPILE is a compile per call, which a statement that runs thousands of times a minute may not afford.

  2. Question 2 of 2 Which pair of fixes is applied to a query by its query_id, with no change to the code?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Query Store hints and plan forcing

    A hint in the code needs a deployment; a Query Store hint needs only the query_id.

Query Store records every plan, and PSP lets one statement keep several

Query Store keeps each query, its plans and their runtime statistics per interval inside the user database. It arrived in SQL Server 2016 and is on by default for databases created on SQL Server 2022 and later. PSP targets the skew of this lesson: at compatibility level 160 the first compile of a skewed predicate can store a dispatcher plan and query variants with plans of their own. Microsoft publishes no skew values for PSP, so check the server rather than assume. The timeline shows when each tool arrived.

Timeline · 4 events in order Tools for parameter-sensitive queries, by version Walk through the versions and see which tool arrived when.
  1. SQL Server 2016

    Query Store and plan forcing Query Store

    Query Store arrives. It keeps queries, their plans and runtime statistics, and a plan can be forced for a query. It is off until someone turns it on.

  2. SQL Server 2017

    Automatic plan correction automatic tuning

    Automatic tuning can force the last known good plan when a plan change makes a query slower, and checks that the forced plan is better.

  3. SQL Server 2022

    PSP, Query Store hints and Query Store on PSP

    PSP optimization arrives at compatibility level 160, Query Store hints let a hint apply without a code change, and Query Store is on by default for new databases.

  4. SQL Server 2025

    Optional parameter plan optimization OPPO

    OPPO arrives at compatibility level 170 and is on by default there. It targets searches written as a column equal to a parameter or the parameter is NULL.

The timeline has 4 events, from SQL Server 2016 to SQL Server 2025.

Checkpoint

Check: Query Store and PSP, by version

  1. Question 1 of 2 From which database compatibility level is PSP optimization on by default?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: 160

    PSP at 160, OPPO at 170; both can be switched off with a database scoped setting.

  2. Question 2 of 2 A new database is created on SQL Server 2019. Is Query Store on?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: No, it is on by default only for databases created on SQL Server 2022 and later

    Turn it on explicitly, with READ_WRITE, wherever you want its history.

Reproducing sniffing and comparing the fixes, with numbers Pro: opens with a Pro, Premium or Ultimate pass

The model estimated the reads; this part reproduces the problem on a server, works out the estimate behind local variables and OPTIMIZE FOR UNKNOWN, and compares every fix by the reads it leaves. Run the scripts on the lab instance and put the server’s counts beside the model’s.

In this part:

  • Reproduce sniffing on a server and read its counts
  • What a local variable and OPTIMIZE FOR UNKNOWN estimate, with lab numbers
  • Compare every fix by its reads and its cost

5 runnable examples (Python, SQL) · about 9 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Query Store, PSP and OPPO on a server, step by step Pro: opens with a Pro, Premium or Ultimate pass

Query Store keeps the history that turns “the query got slow” into a plan and a number. This part finds a plan change in its catalog views, forces and unforces a plan, sets a hint, and reads the dispatcher plans of PSP and OPPO.

In this part:

  • Find the plan change in the Query Store views
  • Force a plan, read the failure columns, and unforce it
  • Set a Query Store hint without touching the code
  • See PSP and OPPO variants as the server reports them

1 diagram · 4 runnable examples (Python, SQL) · about 8 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Practise: place each fix before you run it

Decide which plan is cached and what it costs, then read why each answer is right or wrong:

Practice that adapts to you

Practise this lesson

11 questions about 8 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 11 For which kinds of batch does SQL Server sniff parameter values?

    Choose one answer.

    Show the answer: Question 1 of 11

    Answer: Stored procedures, queries sent through sp_executesql and prepared queries

    Wherever a parameter exists at compile time, the optimizer can read its value.

  2. Question 2 of 11 After each restart of the instance, the first call of a nightly report procedure asks for the largest customer. By noon the report is fast for that customer and slow for small ones. Why?

    Choose one answer.

    Show the answer: Question 2 of 11

    Answer: The restart emptied the plan cache, so the first call compiled the plan sized for the large value, and later calls reuse it

    The plan cache lives in memory. Whoever calls first after it is emptied decides the plan until the next recompile.

  3. Question 3 of 11 A plan compiled for 'new' is cached, and the next call asks for 'paid' (900 rows). How many reads does the model give that call? Read the table of the model.

    Type a number.

    Show the answer: Question 3 of 11

    Answer: 2706 reads

    The seek with key lookups for 900 rows reads 2,706 pages, while the scan would read 1,695.

  4. Question 4 of 11 For 'cancelled' (90 rows) the model compares 273 reads for the seek with lookups and 1,695 for the scan. Which plan does it pick when it compiles for that value?

    Choose one answer.

    Show the answer: Question 4 of 11

    Answer: The seek with key lookups

    The pick follows the rows: below the tipping point the seek wins, above it the scan.

  5. Question 5 of 11 A wider table makes each key lookup cost 5 reads instead of 3. Where does the tipping point move, compared with 564 rows?

    Choose one answer.

    Show the answer: Question 5 of 11

    Answer: Lower, because each row costs more and the lookups reach the scan's reads sooner

    With 5 reads a lookup the crossing falls to a few hundred rows.

  6. Question 6 of 11 What do OPTIMIZE FOR UNKNOWN and a copy of the parameter in a local variable have in common?

    Choose one answer.

    Show the answer: Question 6 of 11

    Answer: Both make the optimizer estimate from the average density instead of a sniffed value

    The estimate is the same for every value, which is why the plan is the same for every call.

  7. Question 7 of 11 Why does a covering index make the order of the calls matter less?

    Choose one answer.

    Show the answer: Question 7 of 11

    Answer: With every column the query reads in the index, no plan needs key lookups, so the seek is cheap for every value

    The lesson's model shows a covering seek reading 3 pages for 10 rows and 578 for 99,000, against a scan of 1,695.

  8. Question 8 of 11 A statement runs 5,000 times a minute with values that vary widely. Which statement about OPTION (RECOMPILE) for it is true?

    Choose one answer.

    Show the answer: Question 8 of 11

    Answer: It gives each call a plan sized for its value, and adds a compile to every call, which a statement this hot may not afford

    Pick RECOMPILE for rare, expensive statements; a hot one needs a plan that is built once.

  9. Question 9 of 11 What does Query Store keep that the plan cache alone does not?

    Choose one answer.

    Show the answer: Question 9 of 11

    Answer: The plans a query has had over time, with runtime statistics per interval

    The history is what lets you compare yesterday's plan with today's.

  10. Question 10 of 11 Which search is the pattern that optional parameter plan optimization targets?

    Choose one answer.

    Show the answer: Question 10 of 11

    Answer: WHERE col = @p OR @p IS NULL

    PSP chooses by the number of rows a value matches; OPPO chooses by whether the parameter is NULL.

  11. Question 11 of 11 A database runs at compatibility level 160 and a statement is still slow for some values. Which conclusion is sound?

    Choose one answer.

    Show the answer: Question 11 of 11

    Answer: PSP being on does not guarantee variants for every statement, so check what the server built for it

    Treat PSP as help that may or may not apply to a statement, and keep the other fixes ready.

Interview questions

Warm-up (fresher to 2–5 years): when does SQL Server sniff a parameter?

While it compiles or recompiles a stored procedure, an sp_executesql query or a prepared query, it reads the current parameter values to estimate rows, and the cached plan serves later calls. That helps when values look alike and hurts when one plan cannot suit a small and a large value.

Three longer questions follow; decide your own first step before you open each one:

  1. Senior to staff

    After a weekend that rebuilt indexes and updated statistics, a dashboard query went from about 80 ms to about 4 s. Query Store is on. Show how you find what changed, decide between forcing the earlier plan and adding a hint, and say what you watch afterwards and when you undo it.

    Model answer, Pro. First step and follow-ups

  2. Mid to senior

    A colleague stops an intermittent slowdown by copying each parameter into a local variable at the top of the procedure. The runtime is now steady but slower for the most common calls. On 100,000 rows where the filter column has 4 distinct values, work out the estimate the optimizer now uses and say what you would do instead.

    Model answer, Pro. First step and follow-ups

Flashcards · 7 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. What is parameter sniffing?

    While compiling, the optimizer reads the parameter values of the first call and estimates from the statistics how many rows match; the plan cache then keeps that plan for every later call. Microsoft calls it parameter sensitivity and applies it to stored procedures, sp_executesql and prepared queries.

  2. When does one cached plan become expensive?

    When the values differ a lot. In the lesson's 100,000-row table status = 'new' matches 10 rows and 'shipped' 99,000, and whichever call comes first decides the plan: the model reads 297,418 pages for the big value on the small value's plan, where a scan reads 1,695.

  3. Which fix for a sniffed plan comes before any hint?

    Statistics and indexes: a covering index holds every column the query reads, so no key lookups remain and the plans stop differing, and current statistics keep the estimates honest. Microsoft advises completing both before any hint.

  4. What do OPTION (RECOMPILE), OPTIMIZE FOR a value and OPTIMIZE FOR UNKNOWN each do?

    RECOMPILE compiles the statement on every call with that call's values and discards the plan afterwards. OPTIMIZE FOR a value compiles as if the parameter held the value you choose. OPTIMIZE FOR UNKNOWN, like a local variable, estimates from the column's average density, so every call gets one plan.

  5. What are PSP optimization and OPPO, and which levels do they need?

    From compatibility level 160, parameter sensitive plan optimization can store a dispatcher plan that sends each call to a query variant chosen by the rows its value matches. From level 170, optional parameter plan optimization gives a search like column = @p OR @p IS NULL one variant for NULL and one for a value.

  6. What does Query Store keep, and where?

    Each query, its plans and their runtime statistics per interval, inside the user database. It arrived in SQL Server 2016 and is on by default for databases created on SQL Server 2022 and later.

  7. Which two fixes change a query's plan without editing its code?

    A Query Store hint, such as RECOMPILE, attached to a query by its query_id, from SQL Server 2022; and plan forcing, which pins a plan Query Store recorded for a query_id so the optimizer tries to use it at every compile.

Key takeaways

  • Parameter sniffing compiles a plan with the first call’s values and reuses it for every later call.
  • In the model one call reads 33 or 297,418 pages depending on which value came first; a scan reads 1,695.
  • Eight fixes exist, and statistics and indexes come before any hint.
  • PSP and OPPO let one statement keep several plans, and Query Store finds regressions by their reads.

Terms in this lesson

optional parameter plan optimization
OPPO, from compatibility level 170: a search such as column = @p OR @p IS NULL can get separate query variants for a NULL parameter and for a value.
parameter sensitive plan optimization
PSP optimization, from compatibility level 160: one parameterized statement can keep a dispatcher plan and several query variants, each with its own plan, chosen by the rows a value matches.
parameter sniffing
SQL Server reads the parameter values of the first call while it compiles a procedure or parameterized query, so the cached plan fits those values and may fit others poorly.
plan cache
The memory area where SQL Server keeps compiled execution plans, so later calls of the same procedure or statement can reuse a plan instead of compiling again.
plan forcing
Pinning a plan that Query Store recorded for a query_id, so the optimizer tries to use that plan whenever the query compiles.
Query Store
A feature of each database that records queries, their execution plans and runtime statistics per time interval, so plan changes can be found and compared.
Query Store hint
A query hint attached to a query by its query_id in Query Store, so it applies without editing the code; available from SQL Server 2022.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.