Что означает фрагментация в куче
Значение фрагментации в куче, которое вы получаете из столбца avg_fragmentation_in_percent
путем запроса sys.dm_db_index_physical_stats
DMV, гласит, что
Логическая фрагментация для индексов или фрагментация экстентов для куч в блоке выделения IN_ROW_DATA.
Далее тот же BOL говорит, что
Это процент неупорядоченных экстентов на листовых страницах кучи. Экстент вне порядка - это экстент, для которого экстент, содержащий текущую страницу для кучи, физически не является следующим экстентом, который содержит предыдущую страницу.
Таким образом, вы можете видеть, что это не свободное место на страницах, выделенных для Heap, а различная последовательность страниц, которая создает фрагментацию.
Это можно продемонстрировать с помощью небольшого теста. Давайте создадим таблицу кучи и вставим в нее несколько записей, а затем проверим фрагментацию.
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')
Таким образом, таблица кучи создается с 50 записями. Ниже показано, как выглядит фрагментация после запроса DMV sys.dm_db_index_physical stats
Вы можете увидеть avg_fragmentation_in_percent
значение столбца 33%. Теперь давайте посмотрим, как устроены страницы. Это можно сделать с помощью недокументированного запроса %%lockres%%
. Запрос будет
SELECT %%lockres%%, * FROM dbo.HeapTest;
И ниже, как выглядит вывод. Прикрепление только соответствующей части. Запрос выдал 50 строк, так как мы вставили 50 строк в нашу таблицу dbo.HeapTest.
Он говорит, что у первой страницы есть идентификатор, 197
у следующей страницы - идентификатор, у 242
последующих страниц - непрерывный идентификатор, пока мы не достигнем идентификатора страницы, 264
потому что после этого мы получаем идентификатор страницы 280
. Таким образом, этот скачок в числах идентификаторов страниц на самом деле вызывает фрагментацию.
Теперь, чтобы не перестроить кучу и снова запустить команду, чтобы увидеть фрагментацию и порядок расположения страниц. Мы получаем фрагментацию, как
Вы можете увидеть фрагментацию сейчас 14%
.
Давайте посмотрим номера страниц, выделенных
У нас есть только один прыжок, все страницы последовательно распределяются по идентификатору страницы. Так как только один скачок фрагментация значительно уменьшилась.
Я снова перестраиваю кучу, и теперь, когда я проверял фрагментацию, она полностью исчезла. И распределение идентификаторов страниц как
Почему фрагментация увеличилась
Теперь относительно того, что могло вызвать рост фрагментации, мы можем подтвердить это тем фактом, что, когда страницы выделяются в куче, они не будут непрерывными, как вы видели выше, что вызвало увеличение значения фрагментации - это скачок идентификатора PAGE, выделенного страницам.
В конце вы также должны иметь в виду, что фрагментация слова для HEAP не имеет никакого значения, как бы вы определили фрагментацию для группы неупорядоченных страниц.
Действительно беспокоюсь о фрагментации
Если вы действительно сталкиваетесь со сценарием, в котором таблица кучи фрагментируется и замедляет запросы, лучше создать кластерный индекс для таблицы, чем перестраивать его. Причина в том, что при перестройке кучи все базовые некластеризованные индексы также перестраиваются, в результате чего процесс перестройки занимает гораздо больше времени, используя много ресурсов и раздувая журнал транзакций. В производственной системе всегда старались бы избежать этого. Павел рассказал об этом в своем разделе «Мифы о куче» .
PS: Пожалуйста, не используйте недокументированную команду в производственной системе. Это было просто для демонстрации.