A lot of times you’ll hear how people are experiencing sudden, intermittent, poor performance on a query, bad parameter sniffing at work, so they’ll fix it by running the following code:
DBCC FREEPROCCACHE();
BOOM!
Yeah, you just nuked the cache on your server because you wanted to take out a single terrorist query. Now, yes, that problematic query is going to recompile and hopefully have a better execution plan. Also, so are all the other queries on your system. That spike in CPU and the slow-down all your business people are experiencing… Your fault for going nuclear.
Instead of a nuke, why not use a sniper rifle to just remove the one problematic plan. Here’s a little piece of code to help out:
DECLARE @PlanHandle VARBINARY(64); SELECT @PlanHandle = deps.plan_handle FROM sys.dm_exec_procedure_stats AS deps WHERE deps.object_id = OBJECT_ID('dbo.SomeProcedureName'); IF @PlanHandle IS NOT NULL BEGIN DBCC FREEPROCCACHE(@PlanHandle); END GO
Take a look at the documentation for FREEPROCCACHE. You can target specific plans using a plan_handle, a sql_handle, or even a resource governor pool by passing pool_name. I take advantage of that with this query to pull the plan_handle from sys.dm_exec_procedure_stats. You could use T-SQL text too, you’d just have to add in sys.dm_exec_query_text to one of the other DMOs that has the plan_handle or sql_handle such as sys.dm_exec_requests or sys.dm_exec_query_stats. However you choose to do it, you can use a targeted approach to remove plans from cache.
Let’s take the nukes off the table.
Want to really get into talking about the plan cache, query tuning, parameter sniffing and the rest? I have two upcoming all day pre-conference seminars. There’s still room at IT/Dev Connections in Las Vegas on September 14th. Click here to register. Also, at Connections, I’m hoping to be able to read your execution plans, so bring the really scary ones. Later that same week, I’ll be at SQL Saturday San Diego and will do a pre-con there on query tuning. Click here to get your seat.
I’ve seen this before but out of curiosity is this any different than running sp_recompile on a problem SP? Or to do a targeted nuke running it on a table?
This just removes the plan from cache. If you want to just recompile it, then you can use sp_recompile.
Or, if you’re not fighting a stored proc but rather a badly-behaved standalone query:
— Find bad plan in cache (make note of plan_handle)
SELECT st.text, qp.query_plan, cp.cacheobjtype, cp.objtype, cp.plan_handle
FROM sys.dm_exec_cached_plans cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp
WHERE st.text LIKE’%snippet of query text%’
— Using plan handle from query above, remove that plan from cache
DBCC FREEPROCCACHE(insert plan handle here)
[…] vs continuous delivery Summarize only filtered values using SUBTOTAL & AGGREGATE formulas Targeted Plan Cache Removal SQL SERVER – Fix @@ServerName Property Value When Incorrect What good is the Data Model without […]
Nice! This code snippet assumes current DB scope, but the DMV is global and object_ids are not unique across multiple DBs. For completeness I would include “AND deps.database_id = DB_ID();” to the WHERE.
Excellent point Mike. Thanks. You’re correct.
By the way, I agree Tracy. I use that approach all the time.
[…] Targeted Plan Cache Removal – Grant Fritchey (Blog|Twitter) […]
I use the approach mentioned by Tracy since our application makes virtually no use of stored procedures. ( .net SQL generated by C# code along with object-relational mapper ORM )