Things I Learned While Rebuilding Seriously Fragmented Indexes on SQL Server
I recently inherited some administration duties for a SQL Server instance. The database was growing out of control and performing poorly. The following is what I learned while trying to improve the state of the indexes.
The primary application database is ~ 85 GB in size and of that total amount there is a single table which is ~34 GB. The single table includes an additional ~6 GB of indexes. The total space on the data drive was ~90 GB.
Needless to say, the performance of the application depends entirely on the performance of that single table. The rules were, I could not add, delete, or disable any of the indexes and I had zero control over the design the database. It was a vendor product and any manipulation at that level would have violated our licensing and support agreement.
There were two goals in de-fragmenting the indexes: 1) Improve Performance and 2) Reclaim misused disk space.
Number 1:
If you have the licensing for Enterprise Edition, use it. SQL Server 2012 Standard Edition does not have the ability to rebuild indexes online. Rebuilding large indexes locks the table while the index is being rebuilt.
Number 2:
Script your index rebuild. You will see all of the possible options and get to take advantage of them. In my scenario, the available disk space on the primary data drive was low. I was afraid to rebuild all of the indexes at once because some of the indexes were larger than the available space. I did have the advantage of a fairly healthy drive which contained only the tempdb. I change the indexes to sort in tempdb (SORT_IN_TEMPDB = ON). This sped up the rebuild and alleviated my concerns about using up the remaining space on the data drive.
Number 3:
Fragmented indexes can use up a lot of unnecessary space. I recovered ~17 GB of space in the data file. I do not think this is a normal result but is indicative of how large and badly fragmented the indexes were.
Number 4:
Do not shrink your data file. I was so excited about the recovery of the space in the data file that I wanted shrink the data file so the drive showed our system engineers how much space I had recovered. Using 20/20 hindsight, this was an irrational thought. My only excuse is it was really early in the AM and I wasn't thinking clearly. So I shrank the data file to recover the unused space and immediately my indexes were severely fragmented again. Shrinking the data file places the data anywhere available on the disk and does not care if it fragments indexes. At least at this point I had the scripts set up from lesson number 2.
Number 5:
Fragmented indexes do cause performance problems, but indexes can not entirely overcome bad database design. That can be another blog post.