Archive

Archive for October, 2011

SQL – Rebuild Index/Fill factor

October 30, 2011 Leave a comment

This week, I have got a challenge to improve the database performance. In this process I have used many techniques and achieved the 80% performance improvement. In this process, I would like to document one of the mainly used tasks in the database maintenance
 
1. Fragmentation of tables
2. Re Organize/Build Index
3. Fill factor
 
Fragmentation concepts:

Fragmentation is the process of data deviation from the Index order in the table/Index
I have created one diagram for easy of understanding

 
Here Index Order gives how the data inside the index are arranged in order and fragmentation is the percentage of data deviated from the order of the index data
Index order is indirectly relates to fragmentation, as the fragmentation increases the performance of database goes down.
We could say, fragmentation of 100% becomes table scan or logically a heap scan so the query performance will go down.
 
Solution
 
Step 1: Calculate the fragmentation
Use the database, to calculate the fragmentation as
 
Here considered only two generic sys tables and join the sys tables to get the information on tables and fragmentation

SELECT  *
FROM    sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED')

SELECT  *
FROM    sys.indexes

SELECT  OBJECT_NAME(IDX.OBJECT_ID) AS TableName,
        IDX.NAME AS IndexName,
        IDXSTAT.avg_fragmentation_in_percent,
        IDXSTAT.*
FROM    sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') IDXSTAT
        JOIN sys.indexes IDX ON IDXSTAT.OBJECT_ID = IDX.OBJECT_ID
                                AND IDXSTAT.INDEX_ID = IDX.INDEX_ID
WHERE   IDXSTAT.avg_fragmentation_in_percent > 30  -- filter condition

 
To extend this query further, presenting the sys table and the join of the sys tables with the limitation of fragmentation in the where clause.
 
Step 2:
 
Here, I prepared a standard script to loop through all database and all the tables to rebuild index with fill factor.
We could customize the script for particular scenario at the commented sections as
 

DECLARE @Database VARCHAR(255) 
DECLARE @Table VARCHAR(255)  
DECLARE @cmd NVARCHAR(500)  
DECLARE @fillfactor INT 

SET @fillfactor = 75  -- Set the required fill factor

DECLARE DatabaseCursor CURSOR
    FOR SELECT  name
        FROM    master.dbo.sysdatabases
        WHERE   name NOT IN ( 'master', 'model', 'msdb', 'tempdb' ) 
     -- Loop through all the databases except the system database
     -- WHERE name IN ('SANDBOX')   -- Enter your database name 
        ORDER BY 1  

OPEN DatabaseCursor  

FETCH NEXT FROM DatabaseCursor INTO @Database  
WHILE @@FETCH_STATUS = 0  
    BEGIN  
		
     -- Create table cursor
        SET @cmd = 'DECLARE TableCursor CURSOR FOR SELECT table_catalog + ''.'' 
                  + table_schema + ''.'' 
                  + table_name as tableName   
                    FROM ' + @Database
                  + '.INFORMATION_SCHEMA.TABLES WHERE table_type = ''BASE TABLE'''
        
        EXEC ( @cmd
             )  
        OPEN TableCursor   

        FETCH NEXT FROM TableCursor INTO @Table   
        WHILE @@FETCH_STATUS = 0   
            BEGIN       
       --DBCC DBREINDEX(@Table,' ',@fillfactor)  -- Not using DBCC DBREINDEX       
      
                SET @cmd = 'ALTER INDEX ALL ON ' + @Table
                         + ' REBUILD WITH (FILLFACTOR = '
                         + CONVERT(VARCHAR(3), @fillfactor) + ')'  
                EXEC ( @cmd
                    )  

                FETCH NEXT FROM TableCursor INTO @Table   
            END   

        CLOSE TableCursor   
        DEALLOCATE TableCursor  

        FETCH NEXT FROM DatabaseCursor INTO @Database  
    END  
CLOSE DatabaseCursor   
DEALLOCATE DatabaseCursor   

 
Points to consider:
 
1. These scripts prepared bases on only the standard SQL sys tables and approached in SQL 2008
2. Presented only the Rebuild of index here as most of the times I came across the rebuilding of index with fragmentation more than 30
3. Rebuilding of index is an expensive operation and the database will into the lock mode so consider the time bandwidth for the maintenance
4. Don’t recommend to use the script directly without assessing the scenario of problem and the solution approaches as every database is different to each other apart from standard similarities

Advertisements
Categories: SQL Server Tags: