Matan Yungman
Microsoft Protection Services (via Log-On Software)
Blog: www.dbnewsfeed.com
Twitter: @MatanYungman
|Things You Can Find In The Plan Cache
What is the Plan CacheWays to explore itHow to successfully leverage itQuerying it to identify problematic
queriesQuerying Execution Plan XML
Agenda
Query Pre - Execution Phases
Optimize
Bind
Parse
Query Execution TimeCPUMemory
The Solution:Save plan for future
reuse
The Process Is Expensive
Built from 4 cache stores• CACHESTORE_OBJCP – Object Plans• CACHESTORE_SQLCP – Ad hoc and
Prepared Plans• CACHESTORE_PHDR – Bound Trees• CACHESTORE_XPROC – Extended
Procedures
“Steals” its memory from the buffer poolEach store is basically a hash tableAge-out algorithm
The Plan Cache
sys.dm_exec_cached_plansOne row per batchUse countsObject type, Cache object typePlan_handle
sys.dm_exec_query_statsOne row per statement in a batchExecution count, Plan generation countIODurationPlan_handle, Sql_handleQuery_hash and Query_plan_hash
Diving In – Views
sys.dm_exec_sql_textPass plan_handle/sql_handle to get batch textUse offsets to get query level text
sys.dm_exec_query_planUse to get the query planReturns XML plan of all the statements in a batch
sys.dm_exec_text_query_planUse to get the plan at the statement levelReturns nvarchar(max). Cast it to XML
sys.dm_exec_plan_attributesUse to determine lack of reuse reasonsAll cache_key attributes must match for reuse to
happen
Diving In - Functions
Objects (Stored Procedures, Functions, Triggers)(ObjectID * DB_ID) % (Hash Table Size)
Ad-hoc and prepared statementsQuery Text HashExact text match is needed
Also for reuse to be possible:Set OptionsUser ID (Schema ID)DB_IDAnd More…
Cache Lookup
Lots of plans with use count of 1Not necessarily user queries
ADO.Net, EXEC(), System QueriesHow to identify:
Search for ad-hoc plans with use count = 1Optimization options:
Optimize for ad hoc workloadsSwitch to parameterized methodsTurn on Forced Parameterization
Try to test it’s appropriate for your systemCan also be used selectively through plan guides
Common Problems: Ad-hoc
SELECT SUM(CAST(size_in_bytes AS BIGINT))/1024.0/1024.0 AS SizeInMB, COUNT(*) AS PlanCountFROM sys.dm_exec_cached_plansWHERE objtype = 'Adhoc' AND cacheobjtype = 'Compiled Plan' AND usecounts = 1
Recommended Query #1
NhibernateString parameter lengths are supplied according
to each specific executionSolution: Nhibernate “prepare_sql” parameter
Linq To SQL & Entity FrameworkSame as NhibernateSolution: Upgrade to Dot Net 4.0
Simple ADO.Net queriesAct as Ad-hoc queriesOptimization options:
Optimize for ad-hoc workloads optionForced parameterizationADO.Net parameterized queries (supply length for
strings)
Common Application Problems
• Can help identify potentially reusable queries• Recommended query #2:
Query_hash & Query_plan_hash
SELECT query_hash,COUNT(*) AS PlanCount FROM sys.dm_exec_query_stats GROUP BY query_hash HAVING COUNT(*) > 1
Plan Cache Memory Limits75% 0-4GB
+ 10% 4Gb-64GB
+ 5% > 64GB
Max number of items per cache store:10007 on 32-bit, 40009 on 64-bit
Numbers are as of SQL Server 2005 SP2
Age-out algorithm based on:Plan generation costUsage
On memory pressure, all plan costs are decreased by 1
Plans with cost = 0 can be evictedAd-hoc plans always enter with cost = 0
Cost incremented by 1 on each reuseFor other plans
Cost is reset to the original value on reuseAd-hoc max cost = 16Prepared max cost = 256No max cost for stored procedures
Automatic Plan Eviction
DBCC FREEPROCCACHEClears all plans
Can also be more specificplan_handle / sql_handle / pool_name
DBCC FREESYSTEMCACHESpecific cache store: ‘SQL Plans’ / ‘Object
Plans’ Undocumented
DBCC FLUSHPROCINDB – Specific database
Manual Plan Eviction
We can answer questions like:Which queries are most IO/CPU/Time
intensive?Absolute numbers or per run
Which database is the most resource intensive?
What is the value a plan was optimized for?
Which queries/objects are frequently recompiled?
And more..
Searching For Problematic Queries
Plan is optimized for first execution’s parametersLocal variable values not known to the optimizerPossible solution: Recompile
Stored procedure level:Create Procedure..With RecompileExec..With Recompile sp_recompile
Statement level:Option (Recompile)
As we saw, it comes with a performance penalty
The Recompile Dilemma
But there’s a problem
Recompile ruins the statistics we rely on when querying the
Plan Cache!
Create Procedure..With Recompile means:“Generate new plan on each run and don’t
cache it”Exec..With Recompile means:
“Generate new plan for this run and don’t cache it”
Option (Rcompile) means:Generate new plan on each runSet execution_count to 1Increase plan_generation_num by 1
The Recompile Dilemma
Local variable problem?Pass the values as parameters from the
outsideUse Dynamic-SQL (preferably
sp_executesql)Parameter Sniffing problem?
Multiple procedures for different cardinalities
Optimize for (@param = value)Optimize for unknown / parameter
maskingPlan freezing
sp_create_plan_guide_from_handleOption (use plan)
Can also be done with a plan guide
Other Solutions
Can answer questions like:Which plans suffer from missing indexes?Which plans suffer from
Implicit_Conversion?Which plans use what index?Which plans’ optimization were timed out?Which plans have inaccurate row count
estimation?And more..
Querying Execution Plan XML
Further Learning:Brent Ozar’s sp_bliz procedure:
http://www.brentozar.com/blitz/Jason Strate’s Plan Cache series
http://www.jasonstrate.com/2011/02/can-you-dig-it-plan-cache-series/
Jason Strate: Using XML to Query Execution Planshttp://dba.sqlpass.org/MeetingArchive.aspx
Querying Execution Plan XML
Reuse is almost always a good thingTry to prevent Plan Cache bloatRemember the effects of RecompileThe Plan Cache is your workload – Get to
know it
Summary
Questions?