@ AaronBertrand hat eine sehr gute Antwort und ist richtig - es kommt darauf an. Ich möchte hinzufügen, dass Sie nur eine Metrik betrachten - die Indexfragmentierung. Das ist ein guter Anfang, aber es gibt noch andere Dinge zu beachten.
Stellen Sie sich das folgende Szenario vor (mit AdventureWorks2014):
select *
from Sales.SalesOrderDetail
where SalesOrderID < 50000;
--modify
delete
from Sales.SalesOrderDetail
where SalesOrderID < 50000;
go
select
SchemaName = s.name,
TableName = t.name,
IndexName = idx.name,
StatsName = st.name,
AvgFragmentationPct = idx.avg_fragmentation_in_percent,
StatsModifications = st.modification_counter,
StatsPctModified = 100.*st.modification_counter / st.unfiltered_rows,
StatsSampleRate = st.sample_rate,
StatsLastUpdate = st.last_updated,
Rows = st.rows
from (
select s.object_id, s.name, sp.modification_counter, sp.unfiltered_rows, s.stats_id, sp.last_updated, sample_rate = (100.*sp.rows_sampled)/sp.unfiltered_rows , sp.rows
from sys.stats s
cross apply sys.dm_db_stats_properties(s.object_id,s.stats_id) sp
) st
left join (
select ips.object_id, i.name, ips.partition_number, ips.avg_fragmentation_in_percent, i.index_id
from sys.dm_db_index_physical_stats(db_id(),null, null, null, default) ips
join sys.indexes i
on ips.index_id = i.index_id
and ips.object_id = i.object_id
) idx
on st.object_id = idx.object_id
and st.stats_id = idx.index_id
join sys.tables t
on st.object_id = t.object_id
join sys.schemas s
on t.schema_id = s.schema_id
where s.name = 'Sales' and t.name = 'SalesOrderDetail'
go
delete
from Sales.SalesOrderDetail
where ProductID = 779
go
select
SchemaName = s.name,
TableName = t.name,
IndexName = idx.name,
StatsName = st.name,
AvgFragmentationPct = idx.avg_fragmentation_in_percent,
StatsModifications = st.modification_counter,
StatsPctModified = 100.*st.modification_counter / st.unfiltered_rows,
StatsSampleRate = st.sample_rate,
StatsLastUpdate = st.last_updated,
Rows = st.rows
from (
select s.object_id, s.name, sp.modification_counter, sp.unfiltered_rows, s.stats_id, sp.last_updated, sample_rate = (100.*sp.rows_sampled)/sp.unfiltered_rows , sp.rows
from sys.stats s
cross apply sys.dm_db_stats_properties(s.object_id,s.stats_id) sp
) st
left join (
select ips.object_id, i.name, ips.partition_number, ips.avg_fragmentation_in_percent, i.index_id
from sys.dm_db_index_physical_stats(db_id(),null, null, null, default) ips
join sys.indexes i
on ips.index_id = i.index_id
and ips.object_id = i.object_id
) idx
on st.object_id = idx.object_id
and st.stats_id = idx.index_id
join sys.tables t
on st.object_id = t.object_id
join sys.schemas s
on t.schema_id = s.schema_id
where s.name = 'Sales' and t.name = 'SalesOrderDetail'
go
Wir erstellen ein neues automatisch erstelltes Statistikobjekt ( _WA_Sys_00000006_44CA3770in diesem Beispiel) durch Filtern SalesOrderIDund löschen dann Zeilen (~ 30.000 davon). Wir führen dann weitere Änderungen ein, indem wir Zeilen mit einer bestimmten löschen ProductID. Dies ist wichtig, da es sich um eine führende Spalte in mindestens einem dieser Indizes / Statistiken handelt, die wiederum aus Gründen der Selektivitätsberechnung (Statistik) und der B-Tree-Durchquerung (Index) wichtig ist.

Die Indexfragmentierung ist nicht so schlecht, also lasst uns neu organisieren.
alter index all on Sales.SalesOrderDetail reorganize;
go
select
SchemaName = s.name,
TableName = t.name,
IndexName = idx.name,
StatsName = st.name,
AvgFragmentationPct = idx.avg_fragmentation_in_percent,
StatsModifications = st.modification_counter,
StatsPctModified = 100.*st.modification_counter / st.unfiltered_rows,
StatsSampleRate = st.sample_rate,
StatsLastUpdate = st.last_updated,
Rows = st.rows
from (
select s.object_id, s.name, sp.modification_counter, sp.unfiltered_rows, s.stats_id, sp.last_updated, sample_rate = (100.*sp.rows_sampled)/sp.unfiltered_rows , sp.rows
from sys.stats s
cross apply sys.dm_db_stats_properties(s.object_id,s.stats_id) sp
) st
left join (
select ips.object_id, i.name, ips.partition_number, ips.avg_fragmentation_in_percent, i.index_id
from sys.dm_db_index_physical_stats(db_id(),null, null, null, default) ips
join sys.indexes i
on ips.index_id = i.index_id
and ips.object_id = i.object_id
) idx
on st.object_id = idx.object_id
and st.stats_id = idx.index_id
join sys.tables t
on st.object_id = t.object_id
join sys.schemas s
on t.schema_id = s.schema_id
where s.name = 'Sales' and t.name = 'SalesOrderDetail'
go

Durch eine Umstrukturierung werden keine Änderungen vorgenommen.
Lassen Sie uns wieder aufbauen:
alter index all on Sales.SalesOrderDetail rebuild;
go
select
SchemaName = s.name,
TableName = t.name,
IndexName = idx.name,
StatsName = st.name,
AvgFragmentationPct = idx.avg_fragmentation_in_percent,
StatsModifications = st.modification_counter,
StatsPctModified = 100.*st.modification_counter / st.unfiltered_rows,
StatsSampleRate = st.sample_rate,
StatsLastUpdate = st.last_updated,
Rows = st.rows
from (
select s.object_id, s.name, sp.modification_counter, sp.unfiltered_rows, s.stats_id, sp.last_updated, sample_rate = (100.*sp.rows_sampled)/sp.unfiltered_rows , sp.rows
from sys.stats s
cross apply sys.dm_db_stats_properties(s.object_id,s.stats_id) sp
) st
left join (
select ips.object_id, i.name, ips.partition_number, ips.avg_fragmentation_in_percent, i.index_id
from sys.dm_db_index_physical_stats(db_id(),null, null, null, default) ips
join sys.indexes i
on ips.index_id = i.index_id
and ips.object_id = i.object_id
) idx
on st.object_id = idx.object_id
and st.stats_id = idx.index_id
join sys.tables t
on st.object_id = t.object_id
join sys.schemas s
on t.schema_id = s.schema_id
where s.name = 'Sales' and t.name = 'SalesOrderDetail'
go

Ok, unsere Fragmentierungszahlen sind bescheiden besser, aber nicht signifikant und Ihrer Meinung nach den Aufwand für den Wiederaufbau im Vergleich zur Reorganisation möglicherweise nicht wert.
Es gibt jedoch noch ein paar andere erwähnenswerte Dinge.
- Durch die Neuerstellung Ihrer Indizes werden auch Ihre Statistiken mit einem vollständigen Scan aktualisiert. Es sollte beachtet werden, dass nur die Statistiken aktualisiert werden, die den Index unterstützen - es werden keine anderen Statistiken aktualisiert (wie durch den traurigen Zustand von belegt
_WA_Sys_00000006_44CA3770).
- Durch die Neuorganisation Ihres Index werden Ihre Statistiken in keiner Weise aktualisiert
Fazit
Es gibt mehr zu bewerten, als ob Sie gute Defragmentierungsraten erhalten oder nicht. Obwohl dies für IO sicherlich wichtig ist, fand ich es auch sehr hilfreich, meine Systeme zu erkunden und zu prüfen, ob ich feststellen kann, wie ich sie am besten warten kann, anstatt sie blind zu aktualisieren, neu zu erstellen und neu zu organisieren.