Cosa significa frammentazione in un mucchio
Il valore di frammentazione in Heap che si ottiene dalla colonna avg_fragmentation_in_percent
interrogando sys.dm_db_index_physical_stats
DMV lo afferma
Frammentazione logica per gli indici o frammentazione dell'estensione per heap nell'unità di allocazione IN_ROW_DATA.
Inoltre lo stesso BOL lo dice
Questa è la percentuale di estensioni non ordinate nelle pagine foglia di un heap. Un'estensione fuori servizio è una per la quale l'estensione che contiene la pagina corrente per un heap non è fisicamente quella successiva dopo l'estensione che contiene la pagina precedente.
Quindi puoi vedere che non è lo spazio libero presente nelle pagine allocate a Heap ma la sequenza variabile di pagine che crea la frammentazione.
Questo può essere dimostrato da un piccolo test. Creiamo una tabella heap e inseriamo alcuni record in essa e quindi controlliamo la frammentazione.
create table dbo.HeapTest
(
Id INT not NULL Default (1),
Col1 char(5000) Not null Default ('Heaps Are Cool')
)
SET NOCOUNT ON
Insert into dbo.Heaptest default values
go 50
select index_type_desc,avg_fragmentation_in_percent,fragment_count,
avg_page_space_used_in_percent,record_count
from sys.dm_db_index_physical_stats(db_id(),object_id('dbo.HeapTest','U'),0,default,'detailed')
Quindi la tabella Heap viene creata con 50 record al suo interno. Di seguito è riportata la frammentazione dopo la query DMV sys.dm_db_index_physical stats
Puoi vedere il avg_fragmentation_in_percent
valore della colonna è del 33%. Ora vediamo come sono organizzate le pagine. Questo può essere fatto utilizzando una query non documentata%%lockres%%
. La query sarebbe
SELECT %%lockres%%, * FROM dbo.HeapTest;
E sotto è come appare l'output. Allegare solo una parte rilevante di esso. La query ha prodotto 50 righe da quando abbiamo inserito 50 righe nella nostra tabella dbo.HeapTest.
Ciò che dice è che la prima pagina ha un ID, 197
la pagina successiva ha un ID, 242
le pagine successive hanno un ID continuo fino a quando non raggiungiamo l'ID della pagina 264
perché dopo otteniamo l'ID della pagina 280
. Quindi questo salto nei numeri di ID pagina è ciò che effettivamente causa la frammentazione.
Ora per ricostruire l'heap ed eseguire nuovamente il comando per vedere la frammentazione e come sono organizzate le pagine. Otteniamo la frammentazione come
Ora puoi vedere la frammentazione 14%
.
Vediamo i numeri di pagina assegnati
Abbiamo solo un resto di riposo a tutte le pagine vengono assegnate in serie l'ID pagina. Da un solo salto la frammentazione è diminuita considerevolmente.
Ho ricostruito di nuovo l'Heap e ora quando ho controllato la frammentazione era completamente sparito. E l'allocazione dell'ID pagina è simile
Perché la frammentazione è aumentata
Ora per quanto riguarda ciò che potrebbe aver causato l'aumento della frammentazione, possiamo confermarlo al fatto che quando le pagine venivano allocate all'heap non sarebbero state continue, come hai visto sopra ciò che ha causato l'aumento del valore di frammentazione è stato il salto nell'ID PAGINA assegnato alle pagine.
Nella parte posteriore della testa dovresti anche tenere presente che la frammentazione della parola per HEAP non ha alcun significato, come definiresti la frammentazione per un gruppo di pagine non ordinate.
Preoccupato per la frammentazione
Se dovessi davvero affrontare uno scenario in cui la tabella heap è frammentata e rallentare le query, sarebbe meglio creare un indice cluster sulla tabella piuttosto che ricostruirlo. Il motivo è che quando si ricostruiscono heap vengono ricostruiti anche tutti gli indici non cluster sottostanti, facendo sì che il processo di ricostruzione impieghi molto più tempo, utilizzando molte risorse e un registro delle transazioni gonfio. Su un sistema di produzione si cercherebbe sempre di evitarlo. Paolo ha trattato questo argomento nella sua sezione miti sull'heap .
PS: Non utilizzare comandi non documentati sul sistema di produzione. Questo era solo per dimostrazione.