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:
Ierakstīt komentāru