SQL Server Troubleshooting: How to remove a bad execution plan from plan cache
Overview
The following article was previously created as a blog in Portuguese, which was posted here. This is the English translation of a blog, with some modifications to fit best to the TechNet WIKI
Everything is going well, your SQL server is with low CPU utilization, high Page Life Expectancy, few fragmented indexes and updated statistics when suddenly some query get a bad execution plan and the CPU usage rises to 100% and you notice that there are multiple sessions of the same application running this same query, which until then had never presented problem, taking too long to return the result and are flooding the SQL Server
This article presents a simple way to remove this bad execution plan from the SQL Server plan cache and save you from an emergency.
First you need the content of sql_handle or plan_handle column of the query that is having trouble to remove the execution plan from the SQL Server plan cache.
Finding the plan_handle
To capture the sql_handle or plan_handle of the query, you can use only one dynamic management view (DMV) and one dynamic management functions (DMF): sys.dm_exec_query_stats and sys.dm_exec_sql_text.
You can query these two objects and filter it using a query snippet that you know that is causing the trouble and sort by totalDurationms or totalCPUms in descending order, as shown below:
SELECT TOP 10
execution_count,
total_elapsed_time / 1000 as totalDurationms,
total_worker_time / 1000 as totalCPUms,
total_logical_reads,
total_physical_reads,
t.text,
sql_handle,
plan_handle
FROM sys.dm_exec_query_stats s
CROSS APPLY sys.dm_exec_sql_text(s.sql_handle) as t
ORDER BY total_elapsed_time DESC
https://felipelauffer.files.wordpress.com/2016/06/screen-shot-2016-06-17-at-11-52-10-pm1.png
Copy the content of plan_handle or sql_handle column of the exact query that is causing the trouble.
Removing Plan Handle from the Plan Cache
Insert the copied content inside the parentheses of the DBCC FREEPROCCACHE command, as shown below:
--DBCC FREEPROCCACHE (<copy the plan_handle here>)
DBCC FREEPROCCACHE (0x0600060020527003B0928B53CC0100000100000000000000000)
https://felipelauffer.files.wordpress.com/2016/06/screen-shot-2016-06-18-at-12-24-18-am.png
Done! The execution plan for your query has been successfully removed from the SQL Server plan cache and probably your server will reduce the high resource utilization and return to respond normally. After this scare try to improve the performance of your query and understand why the execution plan has been altered.
Caution |
---|
|
Reference
- Original post [Portuguese]: Como remover um plano de execução específico do cache do SQL Server
- Microsoft TechNet - DBCC FREEPROCCACHE (Transact-SQL) for SQL Server 2012
- Microsoft TechNet - DBCC FREEPROCCACHE (Transact-SQL) for SQL Server 2008 R2
- 8 different way to remove execution plan