Os índices compactados do SQL Server permanecem compactados na reconstrução sem especificar a compactação de dados?

13

Depois de reconstruir os índices do SQL Server usando a compactação de página ( ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)), as reconstruções subsequentes (como feitas por alguns scripts de manutenção após um certo limite de fragmentação) precisam especificar a compactação de dados novamente? Caso contrário, os índices seriam efetivamente descompactados?

Paul-Sebastian Manole
fonte

Respostas:

22

Os índices permanecem compactados ao reconstruí-los / reorganizá-los.

Criar tabela e índice compactado

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

Verificar compactação

 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';

Resultado

name    data_compression_desc
IX1     PAGE

Reconstruir o índice

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 

Verificar compactação

 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'

Resultado

name    data_compression_desc
IX1     PAGE

Desativá-los e depois reconstruir tem um resultado diferente, pois desativar remove o índice, mantendo a definição do índice.

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

Resultado

name    data_compression_desc

A compactação foi perdida, a definição de compactação também seria perdida ao descartar e criar o índice via SSMS sem adaptar o script de criação de índice.

Por quê?

Como a opção data_compression não é mantida ao criar scripts na instrução de criação de índice.

no entanto, se desativarmos o índice, recrie com compactação e depois reconstrua novamente:

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;

Resultado

name    data_compression_desc
IX1 PAGE

Testando uma reconstrução com a solução de manutenção da Ola hallengren

Os parâmetros são modificados para fins de teste.

Adicione alguns dados para chegar a uma página, pois é necessário para o parâmetro MinNumberOfPages.

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

Execute o proc de otimização de índice para imprimir a instrução.

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;

Resultado:

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

Executando o comando gerado

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

A compressão é mantida

name    data_compression_desc
IX1 PAGE

Testando uma reconstrução com um plano de manutenção (eu defenderia fortemente a solução da ola)

Recriar índices

insira a descrição da imagem aqui

Escolha a tabela de teste

insira a descrição da imagem aqui

Adicione alguns níveis de fragmentação de teste.

insira a descrição da imagem aqui

Insira alguns valores para obter a fragmentação

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

Verifique a porcentagem de fragmentação

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'

Resultado

INDX    avg_fragmentation_in_percent    page_count
IX1 66,6666666666667    3

Execute o plano

insira a descrição da imagem aqui

A parte interessante aqui, ao examinar o relatório do plano, é que a DATA_COMPRESSION = PAGEopção é adicionada ao REBUILDcomando gerado !

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)

Fragmentação:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2

Compressão:

name    data_compression_desc
IX1 PAGE
Randi Vertongen
fonte
Me deparei com você quando descobri que três bancos de dados compactados haviam perdido a compressão e tive que reaplicá-la. Como parte desse trabalho, testei e confirmei seus resultados, mas não faço ideia de como isso aconteceu. A única outra possibilidade que me deparei é que, se os índices estiverem desabilitados, eles perderão a compactação quando reconstruídos. Este não parece ser o caso, de acordo com nossa equipe de ETL. Também fiz essa pergunta no SQLServerCentral: sqlservercentral.com/Forums/2017336/Databases-Lost-Compression Totalmente sem saber como isso aconteceu.
Marvel
Oi @ Marvel, pode ser que algum outro processo tenha recriado índices nos bancos de dados? Por exemplo, alguns aplicativos fazem 'upgrades' onde eles descartam e criam inúmeros índices. No entanto, não creio que alguém possa dar uma explicação clara sem mais detalhes. Da próxima vez que isso acontecer, você poderá encontrar a data de criação do índice e se elas foram recriadas (por exemplo, com a consulta neste link: stackoverflow.com/questions/7579932/… . Caso contrário, você sempre poderá fazer uma pergunta, mas eu faço acho que você precisa para fornecer mais informações.
Randi Vertongen
1
Obrigado Randi! Eu configurei a auditoria SCHEMA_OBJECT_CHANGE_GROUP nos bancos de dados, mas isso definitivamente me ajudará a analisar os logs mais rapidamente. Eu já encontrei um dos culpados - o proprietário dos bancos de dados, aquele que solicitou a compactação modificando tabelas e índices constantemente. Ele não percebeu que, ao criar novas tabelas e mover os dados antigos para dentro e criar novos índices, a compactação seria perdida. :( Eu forneci a ele a maneira correta de criar suas tabelas e índices. Porém, não acho que ele seja o único culpado. Não posso imaginar que ele tenha feito isso com o e
Marvel