By: Jeremy Kadlec | Updated: 2012-05-07 | Comments (19) | Related: > Maintenance
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:
- sp_recompile (SQL Server 2000)
- sp_recompile (SQL Server 2005)
- MSSQLTips.com - Maintenance Category
- 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.
About the author
This author pledges the content of this article is based on professional experience and not AI generated.
View all my tips
Article Last Updated: 2012-05-07