O que significa fragmentação em um heap
O valor de fragmentação no Heap que você obtém da coluna avg_fragmentation_in_percent
consultando o sys.dm_db_index_physical_stats
DMV afirma que
Fragmentação lógica para índices ou fragmentação de extensão para heaps na unidade de alocação IN_ROW_DATA.
Além disso, o mesmo BOL diz que
Essa é a porcentagem de extensões fora de ordem nas páginas de folha de uma pilha. Uma extensão fora de ordem é aquela em que a extensão que contém a página atual de um heap não é fisicamente a próxima extensão após a extensão que contém a página anterior.
Portanto, você pode ver que não é o espaço livre presente nas páginas alocadas ao Heap, mas a sequência variável de páginas que cria a fragmentação.
Isso pode ser demonstrado por um pequeno teste. Vamos criar uma tabela de heap e inserir alguns registros nela e depois verificar a fragmentação.
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')
Portanto, a tabela Heap é criada com 50 registros. Abaixo está a aparência da fragmentação após a consulta DMV sys.dm_db_index_physical stats
Você pode ver que o avg_fragmentation_in_percent
valor da coluna é 33%. Agora vamos ver como as páginas são organizadas. Isso pode ser feito usando uma consulta não documentada%%lockres%%
. A consulta seria
SELECT %%lockres%%, * FROM dbo.HeapTest;
E abaixo está a aparência da saída. Anexando apenas uma parte relevante. A consulta produziu 50 linhas desde que inserimos 50 linhas em nossa tabela dbo.HeapTest.
O que diz é que a primeira página tem ID, 197
a página seguinte tem ID. As 242
páginas subseqüentes têm ID contínuo até chegarmos ao ID da página, 264
porque depois obtemos o ID da página 280
. Portanto, esse salto nos números de identificação da página é o que realmente está causando a fragmentação.
Agora, para não reconstruir o heap e executar o comando novamente para ver a fragmentação e como as páginas são organizadas. Temos fragmentação como
Você pode ver a fragmentação é agora 14%
.
Vamos ver os números de página alocados
Temos apenas um salto para descanso, todas as páginas são alocadas em série. Como apenas uma fragmentação de salto diminuiu consideravelmente.
Reconstruo o Heap novamente e agora, quando verifiquei a fragmentação, ele havia desaparecido completamente. E a alocação de ID da página é como
Por que a fragmentação aumentou
Agora, com relação ao que poderia ter causado o aumento da fragmentação, podemos corroborar o fato de que, quando as páginas estavam sendo alocadas para o heap, elas não seriam contínuas, como você viu acima, o que causou o aumento do valor da fragmentação foi um salto nos IDs de PAGE alocados nas páginas.
Na parte de trás da cabeça, você também deve ter em mente que a palavra fragmentação para HEAP não tem nenhum significado, como você definiria a fragmentação para várias páginas não ordenadas.
Realmente preocupado com a fragmentação
Se você realmente enfrentar um cenário em que a tabela de heap está fragmentada e reduz a velocidade de consultas, seria melhor criar um índice de cluster na tabela do que reconstruí-lo. O motivo é quando você reconstrói a pilha todos os índices não clusterizados subjacentes também são reconstruídos, levando o processo de reconstrução a demorar muito mais tempo, utilizando muitos recursos e inchando o log de transações. Em um sistema de produção, sempre se tentava evitar isso. Paulo cobriu isso em sua seção Mito sobre a pilha .
PS: Por favor, não use comando não documentado no sistema de produção. Isso foi apenas para demonstração.