Changing recovery model removes plans from procedure cache

Did you know that when you change the recovery model of a database – plans for that database are removed from cache ? I didn’t…

SQL 2012 :-

I was doing some performance tuning today, using DMV sys.dm_exec_query_stats to look at summary information for database performance. I normally find this a very useful DMV as a starting point for any database tuning. However, to my surprise, today this DMV held very few rows for the database I was attempting to tune.

A little bit of investigation revealed that my oldest plan in cache for this database was created just after the recovery model had been changed from FULL to SIMPLE. Now, I know that certain SQL Server operations can flush cache, for example changing the max degree of parallelism on a server – but I’d never come across this before..

I wonder how many DBAs are inadvertently flushing procedure cache if they are switching recovery models often – for example, to help with bulk-logged performance ?

Here’s a simple test script to demonstrate :-

1. Create a database

USE Master
GO
CREATE DATABASE PlanCacheTest

2. Confirm the recovery model is full.

SELECT name, recovery_model_desc FROM sys.databases

3 Create a test proc in the database.

USE PlanCacheTest

CREATE PROC PlanCacheProc 
AS 
SELECT * FROM sysindexes ORDER BY dpages DESC

4. Run the proc and check there is an entry in the procedure cache now

EXEC PlanCacheProc 

SELECT * 
FROM sys.dm_exec_query_stats qs 
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt 
WHERE  qt.dbid = DB_ID('PlanCacheTest')

Will return 1 row.

5. Now change the recovery model

ALTER DATABASE  PlanCacheTestSET RECOVERY SIMPLE

6. Now look in the procedure cache again, the plan for my new proc has gone…

SELECT * 
FROM sys.dm_exec_query_stats qs 
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt 
WHERE  qt.dbid = DB_ID('PlanCacheTest')

Will return 0 rows.

USE Master
GO
DROP DATABASE PlanCacheTest

I see the same behaviour switching between all 3 recovery models.

SiteLock