Remove execution plans from the plan cache
Notice there are now two entries in the
DMV output:
The
column shows the value
in the first record, which is the plan executed
once with.
The
column shows the value
in the second record, which is the plan
executed with
, because it was executed twice.
The different
refers to a different execution plan entry in the plan
cache. However, the
value is the same for both entries because they refer to
the same batch.
The execution with
set to OFF has a new
, and it’s available
for reuse for calls that have the same set of SET options. The new plan handle is
necessary because the execution context was reinitialized due to changed SET options.
But that doesn’t trigger a recompile: both entries refer to the same plan and query, as
evidenced by the same
and
values.
What this effectively means is that we have two plan entries in the cache corresponding to the
same batch, and it underscores the importance of making sure that the plan cache affecting
SET options are the same, when the same queries are executed repeatedly, to optimize for plan
reuse and keep plan cache size to its required minimum.
Execution plans remain in the plan cache as long as there is enough memory to store them.
When memory pressure exists, the SQL Server Database Engine uses a cost-based approach to
determine which execution plans to remove from the plan cache. To make a cost-based
decision, the SQL Server Database Engine increases and decreases a current cost variable for
each execution plan according to the following factors.
Tip
A common pitfall is that different clients can have different default values for the SET
options. For example, a connection made through SQL Server Management Studio
automatically sets
to ON, while SQLCMD sets
to
OFF. Executing the same queries from these two clients will result in multiple plans (as
described in the example above).
When a user process inserts an execution plan into the cache, the user process sets the current
cost equal to the original query compile cost; for ad hoc execution plans, the user process sets
the current cost to zero. Thereafter, each time a user process references an execution plan, it
resets the current cost to the original compile cost; for ad hoc execution plans the user process
increases the current cost. For all plans, the maximum value for the current cost is the original
compile cost.
When memory pressure exists, the SQL Server Database Engine responds by removing
execution plans from the plan cache. To determine which plans to remove, the SQL Server
Database Engine repeatedly examines the state of each execution plan and removes plans
when their current cost is zero. An execution plan with zero current cost isn’t removed
automatically when memory pressure exists; it is removed only when the SQL Server Database
Engine examines the plan and the current cost is zero. When examining an execution plan, the
Database Engine pushes the current cost toward zero by decreasing the current
cost if a query isn’t currently using the plan.
The SQL Server Database Engine repeatedly examines the execution plans until enough have
been removed to satisfy memory requirements. While memory pressure exists, an execution
plan might have its cost increased and decreased more than once. When memory pressure no
longer exists, the SQL Server Database Engine stops decreasing the current cost of unused
execution plans and all execution plans remain in the plan cache, even if their cost is zero.
The SQL Server Database Engine uses the resource monitor and user worker threads to free
memory from the plan cache in response to memory pressure. The resource monitor and user
worker threads can examine plans run concurrently to decrease the current cost for each
unused execution plan. The resource monitor removes execution plans from the plan cache
when global memory pressure exists. It frees memory to enforce policies for system memory,
process memory, resource pool memory, and maximum size for all caches.
The maximum size for all caches is a function of the buffer pool size and can’t exceed the
maximum server memory. For more information on configuring the maximum server memory,
see the
setting in.
The user worker threads remove execution plans from the plan cache when single cache
memory pressure exists. They enforce policies for maximum single cache size and maximum
single cache entries.
The following examples illustrate which execution plans get removed from the plan cache:
An execution plan is frequently referenced so that its cost never goes to zero. The plan
remains in the plan cache and isn’t removed unless there is memory pressure and the
current cost is zero.
sys.dm_exec_cached_plans
usecounts
1
SET ANSI_DEFAULTS OFF
usecounts
2
SET ANSI_DEFAULTS ON
memory_object_address
sql_handle
ANSI_DEFAULTS
plan_handle
query_plan_hash
query_hash
000000
0x0300130095555D02C864C10061AB000001000000000000000000000000000000000000000000000000
000000
QUOTED_IDENTIFIER
QUOTED_IDENTIFIER
max server memory
sp_configure