I have a sql script that I use to reorganize indexes with more than 5%
fragmentation and rebuild indexes (ONLINE OFF) with more than 30%
fragmentation. On running this, I found that, the script was working fine but
every iteration updated about 550 indexes. After a run, if I queried the
dynamic management view, it still gave back indexes which were fragmented.
My understanding is that after I do a reorg/rebuild, the entry should
disappear from sys.dm_db_index_physical_stats, if the alter table succeeds.
Question -- what can I do as a DBA, after the script runs to make sure that
the management view gives back updated information and not state information?
My script --
BEGIN
SELECT database_id,object_id,index_id,avg_fragmentation_in_percent
INTO #INDEX_STATS_TEMP
FROM sys.dm_db_index_physical_stats(DB_ID(N'DB_NAME'),NULL, NULL,
NULL, NULL)
WHERE avg_fragmentation_in_percent >= 5
AND index_type_desc != 'HEAP'
-- DECLARE LOCAL VARIABLES FOR THE CURSOR
DECLARE @dbID int,
@tableID int,
@indexID int,
@frag_percent float,
@index_name varchar(100),
@table_name varchar(100),
@sql varchar(1000)
--DEFINE THE CURSOR
DECLARE FRAG_CURSOR CURSOR
FOR SELECT
TEMP.database_id,TEMP.object_id,TEMP.index_id,round(TEMP.avg_fragmentation_in_percent,1,2),S.NAME
FROM #INDEX_STATS_TEMP TEMP,DB_NAME.SYS.INDEXES S
WHERE TEMP.object_id = S.OBJECT_ID AND TEMP.index_id = S.INDEX_ID
OPEN FRAG_CURSOR
FETCH NEXT FROM FRAG_CURSOR INTO
@dbID,@tableID,@indexID,@frag_percent,@index_name
WHILE (@@FETCH_STATUS = 0)
BEGIN
print @tableID
SELECT @table_name = name from DB_NAME.sys.objects where
object_id = @tableID and type = 'U'
IF (@frag_percent <=30)
BEGIN
USE DB_NAME
SET @SQL= 'ALTER INDEX '+@index_name+' ON '+@table_name+'
REORGANIZE'
print @SQL
exec (@SQL)
END
ELSE IF (@frag_percent > 30)
BEGIN
USE DB_NAME
SET @SQL= 'ALTER INDEX '+@index_name+' ON '+@table_name+'
REBUILD WITH (ONLINE = OFF)'
print @SQL
exec (@SQL)
END
SET @SQL = NULL
FETCH NEXT FROM FRAG_CURSOR INTO
@dbID,@tableID,@indexID,@frag_percent,@index_name
END
CLOSE FRAG_CURSOR
DEALLOCATE FRAG_CURSOR
DROP TABLE #INDEX_STATS_TEMP
END
Regards
Jaideep
Geoff N. Hiten - 11 Feb 2008 20:28 GMT
Check the size of the index. I exclude indexes below a particular cutoff
(don't exactly recall what it is) because fragmentation information was not
meaningful.

Signature
Geoff N. Hiten
Senior SQL Infrastructure Consultant
Microsoft SQL Server MVP
>I have a sql script that I use to reorganize indexes with more than 5%
> fragmentation and rebuild indexes (ONLINE OFF) with more than 30%
[quoted text clipped - 116 lines]
>
> Jaideep
Hurme - 11 Feb 2008 22:52 GMT
Try doing update statistics. Statistics will automatically get updated when
an index is rebuilt, but I don't think they do when an index is reorganized
or defragged.

Signature
MG
> Check the size of the index. I exclude indexes below a particular cutoff
> (don't exactly recall what it is) because fragmentation information was not
[quoted text clipped - 120 lines]
> >
> > Jaideep
bubai - 11 Feb 2008 23:33 GMT
Thanks. I will update the statistics. What does the index size have to
defragmentation? Even if the size is less, but is spanning multiple pages,
the fragmentation can happen. I did not understand why did the management
view not get updated after the alter table? Is it solely because update
statistics was not run? Does anyone know how does the management view get
it's data?
Regards
Jaideep
> Try doing update statistics. Statistics will automatically get updated when
> an index is rebuilt, but I don't think they do when an index is reorganized
[quoted text clipped - 124 lines]
> > >
> > > Jaideep
Geoff N. Hiten - 12 Feb 2008 02:42 GMT
In a trivially sized index (< 8 pages) the fragmentation information is
irrelevant. They will never be perfectly defragmented.

Signature
Geoff N. Hiten
Senior SQL Infrastructure Consultant
Microsoft SQL Server MVP
> Thanks. I will update the statistics. What does the index size have to
> defragmentation? Even if the size is less, but is spanning multiple pages,
[quoted text clipped - 148 lines]
>> > >
>> > > Jaideep
Tibor Karaszi - 12 Feb 2008 08:37 GMT
... and for an elaboration of this, read about extents, shared extents etc in Books Online.

Signature
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://sqlblog.com/blogs/tibor_karaszi
> In a trivially sized index (< 8 pages) the fragmentation information is irrelevant. They will
> never be perfectly defragmented.
[quoted text clipped - 138 lines]
>>> > >
>>> > > Jaideep
TheSQLGuru - 12 Feb 2008 02:46 GMT
Are you perhaps using autogrowth to manage the size of your database? How
much free space do you have in the db? Without a LOT of free space,
reorg/rebuild cannot actually accomplish their tasks effectively because
there is no contiguous block of empty space to lay down the pages in order.

Signature
Kevin G. Boles
Indicium Resources, Inc.
SQL Server MVP
kgboles a earthlink dt net
>I have a sql script that I use to reorganize indexes with more than 5%
> fragmentation and rebuild indexes (ONLINE OFF) with more than 30%
[quoted text clipped - 116 lines]
>
> Jaideep
Tim Walker - 04 Mar 2008 11:41 GMT
> I have a sql script that I use to reorganize indexes with more than 5%
> fragmentation and rebuild indexes (ONLINE OFF) with more than 30%
[quoted text clipped - 122 lines]
>
> Jaideep
Tim Walker - 04 Mar 2008 11:56 GMT
I am having the same problem, but I have a more specific example of the issue.
Here is some cut down output from dm_db_index_physical_stats
index_id alloc_unit_type_desc index_depth index_level avg_fragmentation_in_percent page_count
1 IN_ROW_DATA 3 0 50.16835017 297
1 IN_ROW_DATA 3 1 0 2
1 IN_ROW_DATA 3 2 0 1
2 IN_ROW_DATA 3 0 99.46236559 372
2 IN_ROW_DATA 3 1 0 3
2 IN_ROW_DATA 3 2 0 1
In case this doesn't display too well the key point is that at index level
zero there are 297 pages allocated to the clustered index and 372 pages to
the non clustered index.
Except the problem is that this table has no rows in it (although it used to
have)
I have tried rebuilding the indexes using ALTER INDEX, and a DBCC REINDEX
all to no avail,
However DBCC SHOWCONTIG returns the correct results.
Sorry I can't offer a solution but I hope this clarifies the issue I think
we both have.
Let me know if you find one.
Tim Walker - 04 Mar 2008 14:21 GMT
Sorry, just noticed a typo in the way I was doing this which explains the
results. Please ignore my previous post. Apologies again.
> I am having the same problem, but I have a more specific example of the issue.
>
[quoted text clipped - 24 lines]
>
> Let me know if you find one.