solving sql server problems for millions of dbas and developers since 2006



SQL Server DBA Tips SQL Server Developer Tips SQL Server Business Intelligence Tips SQL Server Career Tips SQL Server Tip Categories SQL Server Tutorials SQL Server Webcasts SQL Server Whitepapers SQL Server Tools SQL Server Questions and Answers MSSQLTips Authors About MSSQLTips SQL Server User Groups MSSLQTips Giveaways MSSQLTips Advertising Options

MSSQLTips Facebook Page MSSQLTips LinkedIn Page MSSQLTips RSS Feed MSSQLTips Twitter Page MSSQLTips Google+ Page








Script to Recompile All SQL Server Database Objects

By: | Read Comments (6) | Print

Jeremy is the CTO @ Edgewood Solutions, co-founder of MSSQLTips.com and SQL Server MVP since 2009.



Related Tips: More

Problem

In some of your tips you reference sp_recompile as a stored procedure that needs to be executed during some maintenance related processes.  After doing some basic research it looks like I can execute sp_recompile against a particular stored procedure or against a table so that all objects, typically stored procedures, that reference that object can be recompiled.  I know that sp_updatestats exists to update statistics against all objects in the database.  Does a similar stored procedure in SQL Server exist for sp_recompile?

Solution

sp_recompile is a system stored procedure in SQL Server 2008 R2, 2008, 2005 and 2000 that will recompile an object the next time it runs.  Recompiling an object is advantageous when 'indexes or other changes that affect statistics are made to the database, compiled stored procedures and triggers may lose efficiency.  By recompiling stored procedures and triggers that act on a table, you can reoptimize the queries' (Source = sp_recompile).  In essence the query plan changes and the SQL Server optimizer may not be getting the best query plan based on the recent changes.

In a different scenario, the parameter used to build the query plan may be good for some queries and bad for others.  If this is the case, it is necessary to determine when the stored procedure should be recompiled or determine if the performance is bad enough to have separated stored procedures to support the two different query plans.

Nevertheless, in SQL Server, I am not aware of a system stored procedure that will recompile all of the objects in a similar manner as sp_updatestats.  As such reference the scripts below as a simple means to recompile all of the objects in the database.

SQL Server 2008 R2, 2008 and 2005 Code to Recompile All Objects

CREATE PROCEDURE dbo.spEXECsp_RECOMPILE AS 
/*
----------------------------------------------------------------------------
-- Object Name: dbo.spEXECsp_RECOMPILE 
-- Project: SQL Server Database Maintenance
-- Business Process: SQL Server Database Maintenance
-- Purpose: Execute sp_recompile for all tables in a database
-- Detailed Description: Execute sp_recompile for all tables in a database
-- Database: Admin
-- Dependent Objects: None
-- Called By: TBD
-- Upstream Systems: None
-- Downstream Systems: None
-- 
--------------------------------------------------------------------------------------
-- Rev | CMR | Date Modified  | Developer  | Change Summary
--------------------------------------------------------------------------------------
-- 001 | N\A | 06.07.2007 | JKadlec | Original code
-- 002 | N\A | 05.07.2012 | JKadlec | Updated code for SQL Server 2008 R2
*/

SET NOCOUNT ON 

-- 1 - Declaration statements for all variables
DECLARE @TableName varchar(128)
DECLARE @OwnerName varchar(128)
DECLARE @CMD1 varchar(8000)
DECLARE @TableListLoop int
DECLARE @TableListTable table
(UIDTableList int IDENTITY (1,1),
OwnerName varchar(128),
TableName varchar(128))

-- 2 - Outer loop for populating the database names
INSERT INTO @TableListTable(OwnerName, TableName)
SELECT u.[Name], o.[Name]
FROM sys.objects o
INNER JOIN sys.schemas u
 ON o.schema_id  = u.schema_id
WHERE o.Type = 'U'
ORDER BY o.[Name]

-- 3 - Determine the highest UIDDatabaseList to loop through the records
SELECT @TableListLoop = MAX(UIDTableList) FROM @TableListTable

-- 4 - While condition for looping through the database records
WHILE @TableListLoop > 0
 BEGIN

 -- 5 - Set the @DatabaseName parameter
 SELECT @TableName = TableName,
 @OwnerName = OwnerName
 FROM @TableListTable
 WHERE UIDTableList = @TableListLoop

 -- 6 - String together the final backup command
 SELECT @CMD1 = 'EXEC sp_recompile ' + '[' + @OwnerName + '.' + @TableName + ']' + char(13)

 -- 7 - Execute the final string to complete the backups
 -- SELECT @CMD1
 EXEC (@CMD1)

 -- 8 - Descend through the database list
 SELECT @TableListLoop = @TableListLoop - 1
END

SET NOCOUNT OFF
GO

SQL Server 2000 Code to Recompile All Objects

CREATE PROCEDURE dbo.spEXECsp_RECOMPILE AS 
/*
----------------------------------------------------------------------------
-- Object Name: dbo.spEXECsp_RECOMPILE 
-- Project: SQL Server Database Maintenance
-- Business Process: SQL Server Database Maintenance
-- Purpose: Execute sp_recompile for all tables in a database
-- Detailed Description: Execute sp_recompile for all tables in a database
-- Database: Admin
-- Dependent Objects: None
-- Called By: TBD
-- Upstream Systems: None
-- Downstream Systems: None
-- 
--------------------------------------------------------------------------------------
-- Rev | CMR | Date Modified  | Developer  | Change Summary
--------------------------------------------------------------------------------------
-- 001 | N\A | 06.07.2007 | JKadlec | Original code
*/ 

SET NOCOUNT ON 

-- 1 - Declaration statements for all variables
DECLARE @TableName varchar(128)
DECLARE @OwnerName varchar(128)
DECLARE @CMD1 varchar(8000)
DECLARE @TableListLoop int
DECLARE @TableListTable table
(UIDTableList int IDENTITY (1,1),
OwnerName varchar(128),
TableName varchar(128))

-- 2 - Outer loop for populating the database names
INSERT INTO @TableListTable(OwnerName, TableName)
SELECT u.[Name], o.[Name]
FROM dbo.sysobjects o
INNER JOIN dbo.sysusers u
 ON o.uid = u.uid
WHERE o.Type = 'U'
ORDER BY o.[Name]

-- 3 - Determine the highest UIDDatabaseList to loop through the records
SELECT @TableListLoop = MAX(UIDTableList) FROM @TableListTable

-- 4 - While condition for looping through the database records
WHILE @TableListLoop > 0
 BEGIN

 -- 5 - Set the @DatabaseName parameter
 SELECT @TableName = TableName,
 @OwnerName = OwnerName
 FROM @TableListTable
 WHERE UIDTableList = @TableListLoop

 -- 6 - String together the final backup command
 SELECT @CMD1 = 'EXEC sp_recompile ' + '[' + @OwnerName + '.' + @TableName + ']' + char(13)

 -- 7 - Execute the final string to complete the backups
 -- SELECT @CMD1
 EXEC (@CMD1)

 -- 8 - Descend through the database list
 SELECT @TableListLoop = @TableListLoop - 1
END

SET NOCOUNT OFF
GO

Sample Output

Object 'dbo.sysdiagrams' was successfully marked for recompilation.
Object 'dbo.ShoppingCartContents' was successfully marked for recompilation.
Object 'dbo.ShoppingCart' was successfully marked for recompilation.
Object 'dbo.Customer' was successfully marked for recompilation.
Object 'dbo.CreditCard' was successfully marked for recompilation.
Object 'dbo.Address' was successfully marked for recompilation.

Word of caution

Make sure you have a legitimate reason to recompile all of the objects in your database, especially during core business hours.  Although the process is typically quick, when all of the objects are recompiled, the first execution will be a little slower than normal.  The remaining executions should perform at the normal execution time.  This should be similar behavior as when you restart the SQL Server services or Windows (reboot).

Next Steps

  • Depending on the scenario needed to recompile all objects, consider changing the WHERE clause in the script above to fine tune the number of objects that get recompiled.
  • Depending on the number of objects in your database and the number of objects that will get recompiled, run the script in a development or test database to validate the time needed and the output.
  • Check out these related tips:
  • Script Alternatives - Use DBCC FREEPROCCACHE as an alternative to recompile all objects.  If a script is needed, an alternative to the loop is the sp_msforeachtable system stored procedure.  Just keep in mind that sp_msforeachtable is an undocumented system stored procedure, so check out the web for examples.  Special thanks to Mike B of the MSSQLTips.com community for this feedback.


Related Tips: More | Become a paid author


Last Update: 5/7/2012

Share: Share 






Comments and Feedback:

Wednesday, February 01, 2012 - 12:35:56 AM - Don Read The Tip

Jeremy, just a quick question.

  1. Does the script need to be executed once for (and from) each database ? 
  2. If I need to mark all objects (stored procedures and triggers) in a database to recompile, I am assuming I just need to remove TOP 10 from the Select statement in step 2a ?
Thank you in advance

 


Monday, February 06, 2012 - 12:05:07 PM - Jeremy Kadlec Read The Tip

Don,

1 - Yes the script would need to be run in each database.

2 - I removed the TOP 10 logic in the script.

Please let me know how things go.

I will add this tip to my things to do list to provide a SQL Server 2008 version.

Thank you,
Jeremy Kadlec


Monday, February 06, 2012 - 12:39:51 PM - Don Read The Tip

Jeremy,

I performed reindexing on a database and needed to mark the objects for recompilation. The script worked perfectly. 

Thank you.


Monday, February 06, 2012 - 12:46:09 PM - Jeremy Kadlec Read The Tip

Don,

That is great to hear!

Thank you,
Jeremy Kadlec


Monday, March 26, 2012 - 7:09:48 AM - Sudhir Read The Tip

This script needs small change:

FROM sys.objects o
INNER JOIN sys.schemas u
ON o.schema_id  = u.schema_id
WHERE o.Type = 'U'
ORDER BY o.[Name]

in order to find objects based on schema names.

 


Monday, May 07, 2012 - 11:36:48 AM - Jeremy Kadlec Read The Tip

Sudhir,

Thank you for the feedback.  I have updated the tip to incorporate your code.

Thank you,
Jeremy Kadlec



Post a Comment or Question

Keep it clean and stay on the subject or we may delete your comment.
Your email address is not published. Required fields are marked with an asterisk (*)

*Name   *Email   Notify for updates
Comments
*Enter Code refresh code


 
Sponsor Information
Try the free performance monitoring tool from Idera!

It takes just 5 minutes to connect your SQL Databases to source control. Got 5 minutes? Get started now.

Need SQL Server help and not sure where to turn? Reach out to expert consultants for a Health Check.

Get SQL Server Tips Straight from Kevin Kline.

Join the over million SQL Server Professionals who get their issues resolved daily.

Demystify TempDB Performance and Manageability


Copyright (c) 2006-2012 Edgewood Solutions, LLC All rights reserved
privacy | disclaimer | copyright | advertise | about
authors | contribute | feedback | giveaways | user groups
Some names and products listed are the registered trademarks of their respective owners.


Edgewood Solutions LLC | MSSharePointTips.com | MSSQLTips.com