Index Fragmentation

I have been running the following query to get an in-depth look at index fragmentation and I am a little confused. I run an index rebuild then run the query to verify the rebuild and it states that indexes at "depths" beyond the frst (Index 0) are fragmented. We are experiencing performance issues and I have to eliminate index fragmentation from the equation.

SELECT

DB=DB_NAME(database_id),

[Object]=OBJECT_NAME(OBJECT_ID),*


FROM

sys.dm_db_index_physical_stats(DB_ID(N'MyDatabase'),OBJECT_ID(N'dbo.MyTable'),NULL,NULL,'DETAILED')


DB              Object      index_type_desc       alloc_unit_type_desc    index_depth   index_level   avg_fragmentation_in_percent
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   0                 0.124528698797937  
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   1                 58.9359079704191  
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   2                 100    
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   3                 0    

Thank You In Advance.

July 30th, 2015 3:56pm

Hi,

You did not included page_count in the output. If page_count <1500 there is no need to rebuild that index because such fragmentation is not going to affect any performance.

Please see the article below to know why index can still be fragmented after rebuild

http://social.technet.microsoft.com/wiki/contents/articles/28182.sql-server-in-depth-what-can-cause-index-to-be-still-fragmented-after-rebuild.aspx

Free Windows Admin Tool Kit Click here and download it now
July 30th, 2015 4:14pm

There are two fragmentation types:

Internal Fragmentation: When records are stored non-contiguously inside the page, then it is called internal fragmentation. In other words, internal fragmentation is said to occur if there is unused space between records in a page. This fragmentation occurs through the process of data modifications (INSERT, UPDATE, and DELETE statements) that are made against the table and therefore, to the indexes defined on the table. As these modifications are not equally distributed among the rows of the table and indexes, the fullness of each page can vary over time. This unused space causes poor cache utilization and more I/O, which ultimately leads to poor query performance.

External Fragmentation: When on disk, the physical storage of pages and extents is not contiguous. When the extents of a table are not physically stored contiguously on disk, switching from one extent to another causes higher disk rotations, and this is called Extent Fragmentation.

Non-fragmented pages look like the following:

Statistics for table scan are as follows:

Page read requests: 2
Extent switches: 0
Disk space used by table: 16 KB
avg_fragmentation_in_percent: 0
avg_page_space_used_in_percent: 100

In this case, the statistics for table scan are as follows:

Page read requests: 6
Extent switches: 5
Disk space used by table: 48 KB
avg_fragmentation_in_percent > 80
avg_page_space_used_in_percent: 33

To detect Fragmentation: We can get both types of fragmentation using the DMV: sys.dm_db_index_physical_stats. For the screenshot given below, the query is as follows:

SELECT OBJECT_NAME(OBJECT_ID), index_id,index_type_desc,index_level,
avg_fragmentation_in_percent,avg_page_space_used_in_percent,page_count
FROM sys.dm_db_index_physical_stats
(DB_ID(N'AdventureWorksLT'), NULL, NULL, NULL , 'SAMPLED')
ORDER BY avg_fragmentation_in_percent DESC


Along with other information, there are two important columns that for detecting fragmentation, which are as follows:

avg_fragmentation_in_percent: This is a percentage value that represents external fragmentation. For a clustered table and leaf level of index pages, this is Logical fragmentation, while for heap, this is Extent fragmentation. The lower this value, the better it is. If this value is higher than 10%, some corrective action should be taken.

avg_page_space_used_in_percent: This is an average percentage use of pages that represents to internal fragmentation. Higher the value, the better it is. If this value is lower than 75%, some corrective action should be taken.

Reducing Fragmentation in a Heap: To reduce the fragmentation of a heap, create a clustered index on the table. Creating the clustered index, rearrange the records in an order, and then place the pages contiguously on disk.
Reducing Fragmentation in an Index: There are three choices for reducing fragmentation, and we can choose one according to the percentage of fragmentation:
If avg_fragmentation_in_percent > 5% and < 30%, then use ALTER INDEX REORGANIZE: This statement is replacement for DBCC INDEXDEFRAG to reorder the leaf level pages of the index in a logical order. As this is an online operation, the index is available while the statement is running.
If avg_fragmentation_in_percent > 30%, then use ALTER INDEX REBUILD: This is replacement for DBCC DBREINDEX to rebuild the index online or offline. In such case, we can also use the drop and re-create index method.
(Update: Please note this option is strongly NOT recommended)Drop and re-create the clustered index: Re-creating a clustered index redistributes the data and results in full data pages. The level of fullness can be configured by using the FILLFACTOR option in CREATE INDEX.

July 30th, 2015 4:20pm

I have been running the following query to get an in-depth look at index fragmentation and I am a little confused. I run an index rebuild then run the query to verify the rebuild and it states that indexes at "depths" beyond the frst (Index 0) are fragmented. We are experiencing performance issues and I have to eliminate index fragmentation from the equation.

SELECT

DB=DB_NAME(database_id),

[Object]=OBJECT_NAME(OBJECT_ID),*


FROM

sys.dm_db_index_physical_stats(DB_ID(N'MyDatabase'),OBJECT_ID(N'dbo.MyTable'),NULL,NULL,'DETAILED')


DB              Object      index_type_desc       alloc_unit_type_desc    index_depth   index_level   avg_fragmentation_in_percent
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   0                 0.124528698797937  
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   1                 58.9359079704191  
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   2                 100    
MyDatabase MyTable   CLUSTERED INDEX    IN_ROW_DATA            4                   3                 0    

Thank You In Advance.

Free Windows Admin Tool Kit Click here and download it now
July 30th, 2015 4:30pm

SO how do I resolve EXTERNAL fragmentation?
August 4th, 2015 7:48pm

SO how do I resolve EXTERNAL frag
Free Windows Admin Tool Kit Click here and download it now
August 5th, 2015 1:34am

Not sure I am following here... Internal fragmentation is when the data is not contiguous in the index pages so to resolve internal fragmentation is to rebuild the index. External fragmentation is when the "physical" pages are not contiguous. Rebuilding an index with a different fill factor will resolve this? How do I determine what is the appropriate fill factor? Currently it is 95%. Also, if rebuilding shows that it is less than 1% fragmented, back to my original post, how do I know the index rebuild is working right? How do I force it rebuild those other index levels?

JT

August 5th, 2015 11:32am

Not sure I am following here... Internal fragmentation is when the data is not contiguous in the index pages so to resolve internal fragmentation is to rebuild the index. External fragmentation is when the "physical" pages are not contiguous. Rebuilding an index with a different fill factor will resolve this?

I basically describe SQL Server index fragmentation as logical(external) and Physical(internal). Logical is one where ordering of clustering key does not matches with ordering of data pages this is fragmentation is what we should be worried about

The physical fragmentation which is also referred to as internal is when you have lots of space in index and this happened because of page splits. This tales less priority that logical fragmentation and choosing proper fillfactor while rebuilding index can solve this

How do I determine what is the appropriate fill factor? Currently it is 95%.

There is no special formula for it leave the default to 0 or 100 (0 and 100 both are same) and see how you application behaves. If keeping to this value produces less page splits then this value is good enough . Monitor your Page Splits/sec counter and if you are seeing a high rate, then you may want to reconsider your fill factor.  Please read answers given here and here

Also, if rebuilding shows that it is less than 1% fragmented, back to my original post, how do I know the index rebuild is working right? How do I force it rebuild those other index levels?

If after rebuilding fragmentation is removed then it is definitely working. You can use DMV sys.dm_db_index_physical_stats. Also I guess you have not read the link I shared in first post not all index would show lesser fragmentation after rebuild because for small index FRAGMENTATION DOES NOT MATTERS AT ALL. And there is no need to keep on rebuilding that index. I have written all this in article I shared in my first post


Free Windows Admin Tool Kit Click here and download it now
August 6th, 2015 1:01am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics