Сжатые индексы SQL Server остаются сжатыми при перестроении без указания сжатия данных?

13

После того, как кто-то перестраивает свои индексы SQL Server с использованием сжатия страниц ( ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)), нужно ли в последующих перестроениях (как это делается некоторыми сценариями обслуживания после определенного порога фрагментации) снова указывать сжатие данных? Будут ли индексы эффективно декомпрессированы?

Пол-Себастьян Маноле
источник

Ответы:

22

Индексы остаются сжатыми при их перестройке / реорганизации.

Создать таблицу и сжатый индекс

 CREATE TABLE DBO.TEST_INDX(id int, bla varchar(255));
 CREATE INDEX IX1 ON dbo.TEST_INDX(id)  WITH (DATA_COMPRESSION = PAGE);

Проверьте сжатие

 SELECT i.name, p.data_compression_desc 
 FROM sys.partitions P
 INNER JOIN sys.indexes I ON I.object_id = P.object_id AND I.index_id = P.index_id
 WHERE P.data_compression > 0 and I.name = 'IX1';

Результат

name    data_compression_desc
IX1     PAGE

Перестройте индекс

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 

Проверьте сжатие

 SELECT i.name, p.data_compression_desc 
 FROM sys.partitions P
 INNER JOIN sys.indexes I ON I.object_id = P.object_id AND I.index_id = P.index_id
 WHERE P.data_compression > 0 and I.name = 'IX1'

Результат

name    data_compression_desc
IX1     PAGE

Отключение их, а затем перестройка приводит к другому результату, поскольку отключение удаляет индекс, сохраняя определение индекса.

alter index IX1 on  DBO.TEST_INDX DISABLE ;
alter index IX1 on  DBO.TEST_INDX REBUILD ;

Результат

name    data_compression_desc

Сжатие было потеряно, определение сжатия также было бы потеряно при удалении и создании индекса через SSMS без адаптации сценария создания индекса.

Почему?

Потому что опция data_compression не сохраняется при создании сценария оператора создания индекса.

однако, если мы отключаем индекс, перестраиваем со сжатием, а затем перестраиваем заново:

alter index IX1 on  DBO.TEST_INDX DISABLE ;
alter index IX1 on  DBO.TEST_INDX REBUILD  WITH (DATA_COMPRESSION = PAGE);
alter index IX1 on  DBO.TEST_INDX REBUILD;

Результат

name    data_compression_desc
IX1 PAGE

Тестирование восстановления с помощью технического обслуживания Ola Hallengren

Параметры изменены в целях тестирования.

Добавьте некоторые данные, чтобы попасть на одну страницу, так как это необходимо для параметра MinNumberOfPages.

INSERT INTO dbo.TEST_INDX(id,bla)
VALUES(5,'test');
go 10 

Выполните процедуру оптимизации индекса, чтобы распечатать инструкцию.

EXECUTE dbo.IndexOptimize
@Databases = 'TestDB',
@FragmentationLow = 'INDEX_REBUILD_ONLINE',
@FragmentationMedium = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
@FragmentationLevel1 = 5,
@FragmentationLevel2 = 30,
@Indexes = 'TestDB.DBO.TEST_INDX',
@Execute = 'N',
@MinNumberOfPages = 1;

Результат:

Command: ALTER INDEX [IX1] ON [TestDB].[dbo].[TEST_INDX] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, RESUMABLE = OFF)

Comment: ObjectType: Table, IndexType: NonClustered, ImageTex
t: No, NewLOB: No, FileStream: No, ColumnStore: No, AllowPageLocks: Yes, PageCount: 1, Fragmentation: 0
Outcome: Not Executed
Duration: 00:00:00
Date and time: 2019-01-09 14:48:12

Выполнение сгенерированной команды

ALTER INDEX [IX1] ON [TestDB].[dbo].[TEST_INDX] REBUILD WITH (SORT_IN_TEMPDB = OFF, ONLINE = ON, RESUMABLE = OFF)

Сжатие сохраняется

name    data_compression_desc
IX1 PAGE

Тестирование восстановления с планом обслуживания (я настоятельно рекомендую решение Олы)

Перестройте индексы

введите описание изображения здесь

Выберите тестовую таблицу

введите описание изображения здесь

Добавьте несколько уровней фрагментации теста.

введите описание изображения здесь

Введите некоторые значения для начала фрагментации

INSERT INTO dbo.TEST_INDX(id)
SELECT id from TEST_INDX
go 4

Проверьте процент фрагментации

SELECT 
I.[name] AS  INDX ,
IPS.avg_fragmentation_in_percent,
IPS.page_count
FROM sys.dm_db_index_physical_stats (DB_ID(), object_id('[dbo].[TEST_INDX]'), NULL, NULL, NULL) AS IPS
INNER JOIN sys.indexes AS I ON I.[object_id] = IPS.[object_id]
AND IPS.index_id = I.index_id
WHERE IPS.database_id = DB_ID()
and I.name = 'IX1'

Результат

INDX    avg_fragmentation_in_percent    page_count
IX1 66,6666666666667    3

Запустить план

введите описание изображения здесь

Интересно, что при просмотре отчета о плане DATA_COMPRESSION = PAGEздесь добавляется опция в сгенерированную REBUILDкоманду!

Command:USE [TestDB]
GO
ALTER INDEX [IX1] ON [dbo].[TEST_INDX] REBUILD PARTITION = ALL WITH (PAD_INDEX = ON, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, RESUMABLE = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80, DATA_COMPRESSION = PAGE)

Дробление:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2

Сжатие:

name    data_compression_desc
IX1 PAGE
Рэнди Вертонген
источник
Я наткнулся на ваше сообщение, когда обнаружил, что 3 сжатые базы данных потеряли сжатие, и мне пришлось применить их повторно. В рамках этой работы я проверил и подтвердил ваши результаты, но понятия не имею, как это произошло. Единственная другая возможность, с которой я столкнулся, заключается в том, что, если индексы отключены, они теряют сжатие при перестроении. По-видимому, это не так, согласно нашей команде ETL. Я также задал этот вопрос на SQLServerCentral: sqlservercentral.com/Forums/2017336/Databases-Lost-Compression Совершенно в недоумении, как это произошло.
Marvel
Привет @Marvel, может быть, какой-то другой процесс воссоздает индексы в базах данных? Например, некоторые приложения выполняют «обновления», где они удаляются, и создают бесчисленные индексы. Однако я не думаю, что кто-либо сможет дать четкое объяснение без более подробной информации. В следующий раз, когда это произойдет, вы можете найти дату создания индекса и определить, где они были воссозданы (например, с помощью запроса по этой ссылке: stackoverflow.com/questions/7579932/… . В противном случае вы всегда можете задать вопрос, но я делаю думаю, что вам нужно будет предоставить больше информации
Рэнди Вертонген
1
Спасибо, Рэнди! Я настроил аудит SCHEMA_OBJECT_CHANGE_GROUP для баз данных, но это определенно поможет мне быстрее анализировать журналы. Я уже нашел одного из виновников - владельца баз данных, тот, кто запрашивал сжатие, постоянно изменял таблицы и индексы. Он не понимал, что при создании новых таблиц и перемещении старых данных в & создание новых индексов сжатие будет потеряно. :( Я дал ему правильный путь для создания своих таблиц & индексов Я не думаю , что он является единственным виновником, однако я не могу себе представить , что он сделал это е..
Чудо