piektdiena, 2011. gada 14. janvāris

Indeksu apkope II- ņem vērā dalītus (partitioned) indeksus

Raksta "Indeksu apkope" beigās tika dots "universāls" indeksu pārbūves skripts. Šajā rakstā šis skripts uzlabots, lai tiktu ņemtas vērā indeksa daļas (partitions), shēmas un specifiskus objektu nosaukumus.

Sarežģītāks un vairāk pārdomāts skripts indeksu pārbūvei atrodams šeit. Atšķirība ir tā, ka skripts izmanto gan indeksu pārbūvi gan reorganizāciju, ņem vērā SQL Server versiju, emuāra autors ir daudz vairāk piestrādājis pie tā izveides. Skripts līdz ar to ir daudz garāks. Tas, ko ieteiktu izmantojot jebkuru variantu- saprast, ko tieši skripts dara, kādēļ, kāda no tā jēga un kam būtu jāmainās. Kādās situācijās skripts palīdz, kādās tam nav nekāda nozīme.

[2011-12-28 papildināts] Skripts uzlabots- ņem vērā shēmas un arī objektu nosaukumi var būt jebkādi (iepriekš nobruka uz tukšumiem un tamlīdzīgiem specifiskiem simboliem).

Tātad, lai ņemtu vērā dalītos (partitioned) indeksus:
Declare @DBName sysname
Declare @ObjName sysname
Declare @ObjSchName sysname
Declare @IndName sysname
Declare @SakRebuild DateTime
Declare @Com NvarChar(1000)
Declare @Statuss NvarChar(1000)
Declare @partition_number int
Declare @isPartitioned int


Select db_name(ind.[database_id]) DB,
    sc.name ObjSch,
    object_name(ind.[object_id]) Obj,
    si.[name] Ind, ind.partition_number,
    p.isPartitioned
Into #TTable
From sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'Sampled') ind
    Left Join sys.indexes si on si.Index_ID = ind.Index_id and si.object_id = ind.[object_id]
    Inner Join Sys.Objects so on si.object_id = so.object_id
    Inner Join Sys.Schemas sc on sc.schema_id = so.schema_id
    Left Join (Select object_id, index_id, Case When Count(*) > 1 Then 1 Else 0 End isPartitioned from Sys.Partitions Group By object_id, index_id) p
        on p.Index_ID = ind.Index_id and p.object_id = ind.[object_id]
Where
    OBJECTPROPERTY(ind.[object_id], 'IsMsShipped') = 0
    AND ABS(Case When [Fill_Factor] = 0 Then 100 Else [Fill_Factor] End - ind.avg_page_space_used_in_percent) > 15 -- Samērā daudz pa lieko
    AND ind.alloc_unit_type_desc = 'IN_ROW_DATA' -- uz objektiem ārpus indeksa neskatamies..
    AND ind.page_count > 8 -- tātad- vismaz 8 lapas liels (patiesībā mazs) indekss
    
Declare Cur Cursor For
    Select DB, Obj, ObjSch, Ind, partition_number, isPartitioned
    From #TTable
Open cur
    fetch next from cur into @DBName, @ObjName, @ObjSchName, @IndName, @partition_number, @isPartitioned
    while @@fetch_status = 0
    Begin
    
        SET @Com = N'Alter Index [' + @IndName + N'] On [' + @DBName + N'].[' + @ObjSchName + '].[' + @ObjName + N'] Rebuild';
        IF(@isPartitioned = 1)
            SET @Com = @Com + ' Partition = ' + cast(@partition_number as nvarchar(10))
        SET @Statuss = N'Komanda: ' + @Com;
        SET @SakRebuild = GetDate();
    
        EXECUTE SP_EXECUTESQL @Com;
     
        Set @Statuss = @Statuss + ' Izpildes laiks: ' + Cast(DATEDIFF(SECOND, @SakRebuild, GetDate()) as nvarchar(50)) + ' sekundes'
        Print @Statuss
        fetch next from cur into @DBName, @ObjName, @ObjSchName, @IndName, @partition_number, @isPartitioned
    End


Drop Table #TTable
Close cur
Deallocate cur

Nav komentāru:

Komentāra publicēšana