Що означає фрагментація в купі
Значення фрагментації в Heap, яке ви отримуєте з стовпця avg_fragmentation_in_percent
, запитуючи sys.dm_db_index_physical_stats
DMV, говорить про це
Логічна фрагментація індексів або фрагментація міри для купи в блоці розподілу IN_ROW_DATA.
Далі той самий BOL говорить про це
Це відсоток розмірів, що вийшли з ладу на листкових сторінках купи. Позастарений розмір - це той, для якого ступінь, що містить поточну сторінку для купи, фізично не є наступною мірою після ступеня, що містить попередню сторінку.
Таким чином, ви можете бачити, що не вільний простір, присутній на сторінках, виділених на Heap, а різна послідовність сторінок створює фрагментацію.
Це можна продемонструвати невеликим тестом. Створимо таблицю Heap Table і вставимо в неї деякі записи, а потім перевіримо фрагментацію.
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')
Так створена таблиця Heap з 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: Будь ласка, не використовуйте недокументовану команду на виробничій системі. Це було лише для демонстрації.