Хотя я не знаю конкретных внутренних механизмов, которые отвечают за различия, я могу сказать, что кучи управляются (внутренне) немного иначе, чем кластерные индексы (и, возможно, также некластеризованные индексы):
Удаление строк из кучи, так что одна или несколько страниц данных пусты (без выделенных строк), не обязательно освобождает это пространство. Скорее всего, вам понадобится либо создать, а затем отбросить кластерный индекс в таблице, либо вызвать ALTER TABLE [TableName] REBUILD;
(начиная с SQL Server 2014?). Пожалуйста, посетите страницу Microsoft Docs для DELETE для более подробной информации и опций.
Вставляя отдельные строки (т.е. не основанные на множествеINSERT
) в кучу не заполняет страницы данных так же полно, как это происходит с кластерными индексами. Кластерные индексы будут соответствовать строкам, пока есть место для строки (данные и служебные данные строки) плюс 2-байтовые служебные данные массива слотов. Страницы данных в кучах, однако, не используют количество байтов, оставшихся на странице, а вместо этого используют очень обобщенный индикатор того, насколько заполнена страница, и что сообщается не так много уровней. Уровни примерно такие: 0%, 20%, 50%, 80% и 100% заполнены. И он переключится на 100%, пока еще есть место для другой строки (и на самом деле, если бы такое же количество строк было вставлено в операцию на основе набора, тогда он бы заполнил страницу как можно больше). Конечно, так же, как сDELETE
операции, перестройка кучи будет упаковывать столько строк, сколько поместится на странице данных.
Теперь рассмотрим следующую информацию, взятую из раздела «Когда происходит сжатие страницы» на странице Документов Microsoft для реализации сжатия страницы :
... Когда данные добавляются на первую страницу данных, данные сжимаются строкой. ... Когда страница заполнена, следующая добавляемая строка запускает операцию сжатия страницы. Вся страница просматривается; ...
Следовательно, кажется, что это полностью соответствует этому другому поведению кучи, что им потребуется ALTER TABLE REBUILD, CREATE / DROP кластерного индекса или изменение параметра сжатия данных (все из которых перестраивают кучу) перед записью страниц данных. оптимально. Если кучи не полностью осведомлены о «целых страницах» (до тех пор, пока не будет перестроена куча) и не знают, когда страница определенно заполнится, то они не будут знать, когда начинать операцию сжатия страниц (при работе с обновлениями и отдельными файлами). вставки)
Другая техническая особенность, которая еще больше ограничит некоторые кучи от автоматического применения сжатия страниц (даже если бы они могли это сделать), заключается в том, что применение сжатия потребует перестроения всех некластеризованных индексов для этой кучи (если таковые существуют). На этой связанной странице «Сжатие данных» также говорится:
Изменение параметра сжатия кучи требует перестройки всех некластеризованных индексов в таблице, чтобы они имели указатели на новые расположения строк в куче.
Упоминаемыми «указателями» являются идентификаторы строк (RID), которые представляют собой комбинацию: FileID, PageID и слота / позиции на странице. Эти RID копируются в некластеризованные индексы. Будучи точным физическим местоположением, они иногда быстрее выполняют поиск, чем обходят b-дерево с помощью ключей Clustered Index. Но один недостаток физического местоположения - то, что это может измениться, и это - проблема здесь. Кластерные индексы, однако, не страдают от этой проблемы, потому что их значения ключей копируются в некластеризованные индексы как указатель обратно на кластерный индекс. И значения ключа остаются прежними, даже если их физическое местоположение изменяется.
Также см:
раздел «Управление кучами» на странице Документов Microsoft для куч (таблицы без кластерных индексов) :
Чтобы перестроить кучу для восстановления потерянного пространства, создайте кластерный индекс в куче, а затем отбросьте этот кластерный индекс.
раздел «Рекомендации по использованию сжатия строк и страниц» на странице документов Microsoft для сжатия данных :
Когда куча настроена для сжатия на уровне страниц, страницы получают сжатие на уровне страниц только следующими способами:
- Данные массово импортируются с включенной массовой оптимизацией.
- Данные вставляются с использованием синтаксиса INSERT INTO ... WITH (TABLOCK), и таблица не имеет некластеризованного индекса.
- Таблица перестраивается путем выполнения оператора ALTER TABLE ... REBUILD с параметром сжатия PAGE.
И утверждение цитируется в вопросе.