Approccio migliore per la Reindicizzazione

Sto cercando di ridurre la frammentazione in tutti gli indici di un database in esecuzione in SQL Server 2005.
Attualmente sto cercando di utilizzare l’istruzione ALTER INDEX in collaborazione con sp_MSforeachtable, da applicare a tutti gli indici per tutte le tabelle:

sp_MSforeachtable "ALTER INDEX ALL ON ? REBUILD;"

Ma per qualche motivo questo non sempre sembra funzionare?
Se cerco per un singolo indice, o di tutti gli indici di una tabella, quindi la frammentazione è pulito, sembra proprio essere quando la applico a tutto il database che ho problemi.

In precedenza ho potuto usare il comando DBCC DBREINDEX ma BOL dichiara di essere rimosso nella versione successiva di SQL Server, quindi non ho voglia di usarlo.

Qualcuno mi può dare qualche consiglio sul modo migliore per affrontare la pulizia di tutti gli indici in un database?

Grazie

InformationsquelleAutor Iain Hoult | 2009-07-13



4 Replies
  1. 5

    Se si desidera automatizzare completamente il vostro Indice di SQL Server manutenzione quindi ho seriamente consiglia di controllare Michelle Ufford stored procedure per questo.

    Indice Defrag Script V4.1

    È quello che io considero il miglior indice script di manutenzione che io abbia mai letto.

    Una delle caratteristiche migliori di questo script è che è possibile personalizzare i valori di soglia che si utilizza per determinare se o non RICOSTRUIRE o RIORGANIZZAZIONE di un determinato indice strucutre.

    Fornisce inoltre la possibilità di limitare il numero di core della CPU, che sono utilizzati dalla procedura. Un’ottima opzione se si desidera eseguire lo script su un occupato dal vivo database di produzione.

    Avvertenza: Come con tutti gli internet disponibile codice, assicurarsi di esaminare attentamente prima dell’uso in un ambiente di produzione. È anche più probabile che desidera incorporare la vostra personalizzazione e funzionalità.

  2. 3

    A controllare l’articolo e relativo esempio di script per gestire questa attività in SQL Pazzo (Michelle Ufford sito web:

    http://sqlfool.com/2009/06/index-defrag-script-v30/

    Questo è piuttosto una bella soluzione per gestire questo una volta per tutte!

    Le raccomandazioni di buona pratica è quello di riorganizzare il vostro indice se si dispone di 5-30% di frammentazione, e solo ricostruire, se ha più di 30% di frammentazione. Si può facilmente utilizzare queste soglie o specificare il vostro proprio utilizzando questo script.

    Marc

  3. 1

    O è possibile utilizzare Microsoft indice di script di ricostruzione trovato qui http://msdn.microsoft.com/en-us/library/ms188917.aspx

        -- Ensure a USE <databasename> statement has been executed first.
    SET NOCOUNT ON;
    DECLARE @objectid int;
    DECLARE @indexid int;
    DECLARE @partitioncount bigint;
    DECLARE @schemaname nvarchar(130); 
    DECLARE @objectname nvarchar(130); 
    DECLARE @indexname nvarchar(130); 
    DECLARE @partitionnum bigint;
    DECLARE @partitions bigint;
    DECLARE @frag float;
    DECLARE @command nvarchar(4000); 
    -- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function 
    -- and convert object and index IDs to names.
    SELECT
        object_id AS objectid,
        index_id AS indexid,
        partition_number AS partitionnum,
        avg_fragmentation_in_percent AS frag
    INTO #work_to_do
    FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
    WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;
    
    -- Declare the cursor for the list of partitions to be processed.
    DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;
    
    -- Open the cursor.
    OPEN partitions;
    
    -- Loop through the partitions.
    WHILE (1=1)
        BEGIN;
            FETCH NEXT
               FROM partitions
               INTO @objectid, @indexid, @partitionnum, @frag;
            IF @@FETCH_STATUS < 0 BREAK;
            SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
            FROM sys.objects AS o
            JOIN sys.schemas as s ON s.schema_id = o.schema_id
            WHERE o.object_id = @objectid;
            SELECT @indexname = QUOTENAME(name)
            FROM sys.indexes
            WHERE  object_id = @objectid AND index_id = @indexid;
            SELECT @partitioncount = count (*)
            FROM sys.partitions
            WHERE object_id = @objectid AND index_id = @indexid;
    
    -- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.
            IF @frag < 30.0
                SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
            IF @frag >= 30.0
                SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
            IF @partitioncount > 1
                SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10));
            EXEC (@command);
            PRINT N'Executed: ' + @command;
        END;
    
    -- Close and deallocate the cursor.
    CLOSE partitions;
    DEALLOCATE partitions;
    
    -- Drop the temporary table.
    DROP TABLE #work_to_do;
    GO

    Io uso questo script con SQL Server Agent per automatizzare le attività. Spero che questo aiuta.

Lascia un commento