• subscribe
October 30, 2008 12:00 AM

Three-In-One Database Maintenance Solution

Back up databases, check their integrity, and optimize indexes
SQL Server Pro
InstantDoc ID #100178
Downloads
100178.zip

Maintaining databases is an important but time-consuming job. I wrote a script, MaintenanceSolution.sql, that lets you easily perform three common maintenance tasks: backing up databases, checking the integrity of databases, and optimizing indexes. The script is set up so that you can call its three main stored procedures— DatabaseBackup, IndexOptimize, and Database- IntegrityCheck—separately. Thus, you can perform each task independently on the databases you specify.

MaintenanceSolution.sql is not only easy to use but also offers features such as dynamic index optimization. Rebuilding and reorganizing indexes dynamically has a number of advantages. It lets you rebuild or reorganize only the indexes that need to be rebuilt or reorganized, so locking and blocking are minimized and fewer system resources are used. This, in turn, can result in higher availability and reduce the size of differential and transaction log backups.

MaintenanceSolution.sql works on the Standard, Enterprise, Workgroup, Express, and Developer Editions of SQL Server 2008 and SQL Server 2005 SP2 running on X86, X64, or IA64 platforms. The solution is supported on the same OSs that SQL Server supports. You can download Maintenance- Solution.sql by clicking the 100178.zip hotlink at the top of this page. Aternatively, you can download the script at http://ola.hallengren.com.

How to Back Up Databases
DatabaseBackup is the stored procedure in MaintenanceSolution. sql that performs database backups. When you call this stored procedure, it creates a backup directory, performs a database backup, verifies the backup file, then deletes any old backup file for each database you specify. You specify the database to back up and other details using an EXECUTE statement such as

EXECUTE dbo.DatabaseBackup
@Databases = 'USER_DATABASES',
@Directory = 'C:\Backup',
@BackupType = 'FULL',
@Verify = 'Y',
@CleanupTime = 24

This statement tells DatabaseBackup to perform a full backup of all user databases, verify the backups, then delete any backup files older than 24 hours.

Let’s take a closer look at the EXECUTE statement. You use the @Databases parameter to specify the databases you want to back up. You can select all user databases by specifying 'USER_DATABASES' or select all system databases by specifying 'SYSTEM_ DATABASES'. You can exclude databases from the user databases using the syntax

@Databases =
  'USER_DATABASES, -Database1, -Database2'

where -Database1 and -Database2 are the names of the databases you want to exclude. With this setup, you can, for example, have a backup strategy for one database and another backup strategy for all other databases.

Alternatively, you can back up an individual database by specifying the database’s name, following the syntax

@Databases = 'Database1'

To back up two or more individual databases, follow the syntax

@Databases = 'Database1, Database2'

Besides the DatabaseBackup stored procedure, the IndexOptimize and DatabaseIntegrityCheck stored procedures use the @Databases parameter.

The @BackupType parameter identifies the backup type. The stored procedure can perform full backups ('FULL'), differential backups ('DIFF'), or transaction log backups ('LOG') on the databases you specify.

You use the @Directory parameter to specify the backup root directory, under which DatabaseBackup creates a directory structure consisting of the SQL Server instance name, database name, and backup type. So, for example, if your SQL Server instance is Server1$Instance1 and you specify 'AdventureWorks' for the @Databases parameter, 'C:\Backup' for the @Directory parameter, and 'FULL' for the @Backup- Type parameter, the stored procedure creates the directory structure C:\Backup\Server1$Instance1\AdventureWorks FULL. Each backup file’s name consists of the SQL Server instance name, database name, backup type, and date and time of the backup. In this example, the filename would be Server1$Instance1_ AdventureWorks_FULL_20080904_000001.bak.

The last two parameters are @Verify and @CleanupTime. The @Verify parameter controls whether the backup file should be verified ('Y') or not ('N'). The @CleanupTime parameter specifies when to delete old backup files, assuming the backup and the verification (if that was selected) was successful.

How to Optimize Indexes
Although there aren’t any set rules when it comes to determining when and how to optimize indexes, there are some basic concepts to guide you:

  • Whether an index should be rebuilt, reorganized, or left untouched depends on the index’s fragmentation level. Highly fragmented indexes (typically more than 30 percent fragmented) should be rebuilt. Indexes with little fragmentation (typically less than 5 percent fragmented) should be left alone. Moderately fragmented indexes (typically between 5 percent and 30 percent fragmented) should be reorganized. (For more information about this concept, see “Reorganizing and Rebuilding Indexes” in SQL Server 2008 Books Online—BOL—at msdn.microsoft.com/en-us/library/ms189858.aspx.)
  • Index fragmentation in a very small table has no impact on performance.
  • When an index is rebuilt, the statistics are always rebuilt and therefore updated. However, when an index is reorganized, the statistics aren’t updated. Therefore, you might want to update the statistics after an index is reorganized.
  • An index can be rebuilt online or offline. An offline rebuild is faster than an online rebuild. (Note that only the Enterprise and Developer Editions of SQL Server 2008 and SQL Server 2005 support online rebuilds.)
  • When an index contains a large object (LOB) column, an online rebuild can’t be done.

Continue to page 2



ARTICLE TOOLS

Comments
  • BRIAN
    3 years ago
    Feb 02, 2009

    I work on a moderate size DB.
    • 12 million inserts and 10 million updates in a 12 hour workday.
    • 10 million deletes and Index maintenance at night.

    Our largest table ( 660,000,000 rows)
    • 8.5 million inserts
    • 8 million updates
    • 7.5 million deletes daily.
    • Organized by time.
    • Fragment about 2% daily.

    We were running an index maintenance regime like you propose.
    On the largest table, ran a index defrag each night, taking 6 hours.

    One day we ‘accidently’ did a offline rebuild. Took 30 minutes. Sweet.

    Funny thing all our queries got faster. I mean noticeable faster.

    We realized it was because the defrag only worked on leaf nodes. Over a period of two years the BTree index nodes got horrible unbalanced.

    Insert, update and select activity was occurring at the most recent entries and delete and the lest recent entries. These pages became 50% fragmented due to page splits, while daily table fragmentation was around 2%.

    We kept reducing the point at which we did a rebuild, till we found the point at which it made no difference in performance. 4%.

    We could have done the rebuild every three days, but decided to do it daily. If it failed for any reason, we had few days to fix it before customers noticed. A nice side effect is they stopped worrying when I’d want to take a few days off (I’m the only full time DBA here)

  • Karen
    4 years ago
    Dec 19, 2008

    I'm glad that you found the article useful. I'll pass along your comment to Ola. I'm sure he'll appreciate it!


    Karen Bemowski, senior editor
    SQL Server Magazine, Windows IT Pro

  • Alan
    4 years ago
    Dec 18, 2008

    probably learned more by reading this article than all the Microsoft help files on the subject, although I was glad I read them first - it gave me some background - but this really put things into my hands! Thanks! Very useful tool.

You must log on before posting a comment.

Are you a new visitor? Register Here