none
Alle Indizes einer DB defragmentieren RRS feed

  • Frage

  • Hallo zusammen,

     

    ist es möglich, bzw gibt es ein Script, alle Indizies einer DB, oder luxeriöser, die eine Fragmentierung von >= XX% haben zu defragmentieren?

    Ich müsste ja sonst für jeden Index ein solches Statement absetzen.

    ALTER INDEX  idm_pk_angebotsartikel_woche_aktion_id
    on  Artikelbedarf
    REORGANIZE

    Oder steht die Fragmentierung in einer systabelle, so das dich die durchcursorn könnte?

     

    Danke

    Gruß Andre

     

     

    Montag, 26. Juli 2010 14:05

Antworten

  • Hallo Andre,

    gibt es und das sogar in der BOL zum SQL Server 2000 zu "DBCC SHOWCONTIG", siehe dort Punkt "E. Use DBCC SHOWCONTIG and DBCC INDEXDEFRAG to defragment the indexes in a database"

    Mit SQL Server ab 2005 geht es etwas einfacher über DMV statt DBCC SHOWCONTIG:

    -- Indizes defragmenitieren (SQL 2005)

    DECLARE @TableName sysname;

    DECLARE @IndexID smallint;

     

    -- Alle relevanten Indizes ermitteln

    DECLARE Fragment CURSOR LOCAL FOR

        SELECT OBJ.name AS TableName, IDX.index_id AS IndexID

        FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) AS FRG

             INNER JOIN sys.sysobjects AS OBJ

                 ON FRG.object_id = OBJ.id

             INNER JOIN sys.indexes AS IDX

                 ON FRG.index_id = IDX.index_id

                    AND FRG.object_id = IDX.object_id

        -- Nur wirklich fragmentierte IDX rausfiltern

        WHERE IDX.index_id > 0                          -- keine Heaps

              AND FRG.avg_fragment_size_in_pages > 1    -- min. über eine Seite

              AND FRG.avg_fragmentation_in_percent > 10 -- min. über 10%

        ORDER BY FRG.fragment_count DESC, FRG.page_count DESC, FRG.avg_fragment_size_in_pages DESC

     

    -- Open the cursor

    OPEN Fragment

     

    FETCH NEXT FROM Fragment

               INTO @TableName, @IndexID

    WHILE @@FETCH_STATUS = 0

    BEGIN

       

    PRINT @Tablename + ' -- ' + convert(varchar(10), @IndexID)

     

        FETCH NEXT FROM Fragment

                   INTO @TableName, @IndexID

        DBCC INDEXDEFRAG (0, @TableName, @IndexID) WITH NO_INFOMSGS

    END

     

    CLOSE Fragment

    DEALLOCATE Fragment

     

     


    Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de

    • Als Antwort markiert AndreT78 Montag, 26. Juli 2010 14:27
    Montag, 26. Juli 2010 14:16

Alle Antworten

  • Hallo Andre,

    gibt es und das sogar in der BOL zum SQL Server 2000 zu "DBCC SHOWCONTIG", siehe dort Punkt "E. Use DBCC SHOWCONTIG and DBCC INDEXDEFRAG to defragment the indexes in a database"

    Mit SQL Server ab 2005 geht es etwas einfacher über DMV statt DBCC SHOWCONTIG:

    -- Indizes defragmenitieren (SQL 2005)

    DECLARE @TableName sysname;

    DECLARE @IndexID smallint;

     

    -- Alle relevanten Indizes ermitteln

    DECLARE Fragment CURSOR LOCAL FOR

        SELECT OBJ.name AS TableName, IDX.index_id AS IndexID

        FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) AS FRG

             INNER JOIN sys.sysobjects AS OBJ

                 ON FRG.object_id = OBJ.id

             INNER JOIN sys.indexes AS IDX

                 ON FRG.index_id = IDX.index_id

                    AND FRG.object_id = IDX.object_id

        -- Nur wirklich fragmentierte IDX rausfiltern

        WHERE IDX.index_id > 0                          -- keine Heaps

              AND FRG.avg_fragment_size_in_pages > 1    -- min. über eine Seite

              AND FRG.avg_fragmentation_in_percent > 10 -- min. über 10%

        ORDER BY FRG.fragment_count DESC, FRG.page_count DESC, FRG.avg_fragment_size_in_pages DESC

     

    -- Open the cursor

    OPEN Fragment

     

    FETCH NEXT FROM Fragment

               INTO @TableName, @IndexID

    WHILE @@FETCH_STATUS = 0

    BEGIN

       

    PRINT @Tablename + ' -- ' + convert(varchar(10), @IndexID)

     

        FETCH NEXT FROM Fragment

                   INTO @TableName, @IndexID

        DBCC INDEXDEFRAG (0, @TableName, @IndexID) WITH NO_INFOMSGS

    END

     

    CLOSE Fragment

    DEALLOCATE Fragment

     

     


    Olaf Helper ----------- * cogito ergo sum * errare humanum est * quote erat demonstrandum * Wenn ich denke, ist das ein Fehler und das beweise ich täglich http://olafhelper.over-blog.de

    • Als Antwort markiert AndreT78 Montag, 26. Juli 2010 14:27
    Montag, 26. Juli 2010 14:16
  • Hallo Olaf,

     

    vielen Dank, hat wunderbar geklappt.

     

    Gruß Andre

    Donnerstag, 29. Juli 2010 06:08