To solve this problem, you can run the DMV queries to look for missing indexes in MSDB. For example on one of the sql servers I have, the DMV shows missing indexes:
[type],
[database_name],
[backup_finish_date]
)
INCLUDE ([backup_size]);
On an out of the box, non-optimized MSDB, typically you would see few more missing indexes recommendations.
I thought at some point in the past I had come across a script online to create necessary indexes in MSDB. The only one I could find today that looked more comprehensive than others is this one:
A second option, or maybe a complimentary option to adding missing indexes in the MSDB, you can also purge/remove old history records from the MSDB. Fortunately SQL Server comes with built-in, system stored procedures you can use to accomplish this. All you need to provide to is how far back history records you want to keep and anything older will be deleted. In the following script you provide the value for the @days parameter and anything older will be purged out of the select history tables from the MSDB.
/* Using the buil-in system stored procedures, purges history records from MSDB: - Backup History - Jobs history - Mantainance plan logs history - DB mail history */ use msdb go -- Add index on backupset table to improve performance if not exists(select * from sys.indexes where name = 'idx__backupset_backup_finish_date_for_cleanup') CREATE NONCLUSTERED INDEX idx__backupset_backup_finish_date_for_cleanup ON [dbo].[backupset] ([backup_finish_date]) INCLUDE ([media_set_id]) go declare @days int, @delete_before_date datetime
-- Delete history records older than x days
set @days = 365
set @delete_before_date = GETDATE()-@days
print 'Cleaning up backup history....'
exec sp_delete_backuphistory @oldest_date = @delete_before_date
print 'Cleaning up job history....'
EXECUTE dbo.sp_purge_jobhistory @oldest_date = @delete_before_date
print 'Cleaning up mantainance plan logs history....'
EXEC sp_maintplan_delete_log @oldest_time = @delete_before_date
print 'Cleaning up db mail history....'
exec sysmail_delete_mailitems_sp @sent_before = @delete_before_date
exec sysmail_delete_log_sp @logged_before = @delete_before_date
For the job history tables, there is a GUI option as well. Connect to the SQL Server instance in the SSMS then navigate to the SQL Server Agent job, right click then click on the Properties at the bottom in the Pop up menu: