views:

209

answers:

2
+3  Q: 

Index Maintenance

What is Index Maintenance and how do I do it? How frequently do I have to do it? What are the benefits? This is related to a transaction table which is subject to frequently modifications; all DML operations will be run on that table.

+1  A: 

In general, a DBMS will look after the index automatically so that it still works. However, with enough insert, delete and update operations, it is conceivable that there will be room for improvement in the index. That is, if the index were dropped and recreated, the resulting index would be smaller and more efficient than the modified index. And, ultimately, smaller indexes mean fewer I/O operations, and I/O operations are vastly more expensive than calculations.

There may be answers specific to SQL Server that I'm not aware of, but:

  • Index maintenance would be a process that makes an index perform better.
  • One way to do index maintenance is to drop and rebuild an index.
  • Another way might be to alter the table in such a way that the indexes have to be rebuilt (cluster it, perhaps).
  • You probably don't need to do it very often, but it will depend primarily on the quality of MS SQL Server and the way it handles indexes. I'd expect that to be at least adequate. Maybe once a month, if you have convenient down-time available to do it. Otherwise, less frequently to not at all.
  • The benefit is less space used by the index and better performance using the index.
Jonathan Leffler
Thank, when I create the index first time, will be no I/O operations? and another dought regarding the size ,the size of the index will grow with data/transactions,after some time I droped and recreated the same index will it be down the size and I/O operations
rmdussa
If the table has 10,000,000 records in it when you create the index, there will be I/O; if it has 0 records, almost no I/O. What happens to an index as you drop some records and add others and keep the total population of records approximately constant depends, but typically, it will grow gently. Some patterns are worse than others. For example, if you have a monotonically increasing identity column and always delete at the low end and add at the high end, it can upset the balance of the index structures. But I'm not an MS SQL Server expert - witness the disagreement with my frequency idea.
Jonathan Leffler
+5  A: 

I second everything that Jonathan said - except for the frequency of index maintenance.

Well, if you happen to have a poorly designed index (such as a clustered index on a GUID key), you might actually need to do it at least every night - or even during the day, too.

As a general rule of thumb: if your index fragmentation is below 5%, all is fine. If you have fragmentation between 5% and approx. 30%, you should do an index reorganization:

ALTER INDEX (your index name) ON (your table name) REORGANIZE

If your index has index fragmentation of more than 30%, you need to rebuild it completely:

ALTER INDEX (your index name) ON (your table name) REBUILD

Rebuilding an index can be disruptive - try to do it at off-hours, e.g. during the night.

In order to determine index fragmentation, you can use this DMV query:

SELECT 
    t.NAME 'Table name',
    i.NAME 'Index name',
    ips.index_type_desc,
    ips.alloc_unit_type_desc,
    ips.index_depth,
    ips.index_level,
    ips.avg_fragmentation_in_percent,
    ips.fragment_count,
    ips.avg_fragment_size_in_pages,
    ips.page_count,
    ips.avg_page_space_used_in_percent,
    ips.record_count,
    ips.ghost_record_count,
    ips.Version_ghost_record_count,
    ips.min_record_size_in_bytes,
    ips.max_record_size_in_bytes,
    ips.avg_record_size_in_bytes,
    ips.forwarded_record_count
FROM 
    sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') ips
INNER JOIN  
    sys.tables t ON ips.OBJECT_ID = t.Object_ID
INNER JOIN  
    sys.indexes i ON ips.index_id = i.index_id AND ips.OBJECT_ID = i.object_id
WHERE
    AVG_FRAGMENTATION_IN_PERCENT > 0.0
ORDER BY
    AVG_FRAGMENTATION_IN_PERCENT, fragment_count

Michelle Ufford has a great automatic index defrag script - highly recommended! Or then you should look into setting up SQL Server maintenance plans which can run e.g. every night and clean up your indices.

Marc

marc_s
Thanks, when I create the index first time, will be no I/O operations? and another dought regarding the size ,the size of the index will grow with data/transactions,after some time I droped and recreated the same index will it be down the size and I/O operations
rmdussa
Oh sure - creating an index will cause potentially lots of I/O operations! The size of the index depends on the number of rows in your table - when you delete a lot of rows, rebuilding the index might reduce its size slightly, because the space formerly used by deleted rows can be reclaimed - but the number of rows per table times the number of bytes in your index (sum of the index fields) will be needed - there's no magic there.
marc_s
should I be looking at avg_fragmentation_in_percent in regards to your <5, >5 <30 advice? what about >30? rebuild them?
KM
Yes, exactly - that's the average fragmentation that your index has. Under 5 is ok, 5-30 suggest reorganize, 30 and up rebuild.
marc_s
what's with the rows from this query where the index name is NULL, they are listed as index_type_desc="HEAP". I couldn't get the given alter index commands to run for them. just ignore them?
KM
do you need to update statistics or recompile stored procedures after doing the rebuild or reorganize?
KM
If you're putting all of this into a maintenance plan, I would definitely also update statistics. Not necessary after a rebuild, if I remember correctly (this completely rebuilds the index), but could be useful after a reorganize
marc_s