What is
Fragmentation? How to detect fragmentation and how to eliminate it?
Storing data non-contiguously on
disk is known as fragmentation.
We can classify fragmentation
into two 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.
Index pages
also maintain a logical order of pages inside the extent. Every index page is
linked with previous and next page in the logical order of column data.
However, because of Page Split, the pages turn into out-of-order pages. An
out-of-order page is a page for which the next physical page allocated to the
index is not the page pointed to by the next-pagepointer in the
current leaf page. This is called Logical Fragmentation.
How 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 *
FROM sys.dm_db_index_physical_stats
(DB_ID(N'DBNAME
FROM sys.dm_db_index_physical_stats
(DB_ID(N'DBNAME
'), NULL, NULL, NULL , 'SAMPLED')
ORDER BY avg_fragmentation_in_percent DESC
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:
- 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 INDEXREORGANIZE: 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.
It was so nice article. I was really satisfied by seeing this article. SQL server dba Online Training
ReplyDelete