¿Los índices comprimidos de SQL Server permanecen comprimidos en la reconstrucción sin especificar la compresión de datos?

13

Después de que uno reconstruye sus índices de SQL Server utilizando la compresión de página ( ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)), ¿las reconstrucciones posteriores (como lo hacen algunos scripts de mantenimiento que superan un cierto umbral de fragmentación) necesitan especificar nuevamente la compresión de datos? ¿Los índices se descomprimirían efectivamente?

Paul-Sebastian Manole
fuente

Respuestas:

22

Los índices permanecen comprimidos al reconstruirlos / reorganizarlos.

Crear tabla e índice comprimido

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

Comprobar compresión

 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 el índice

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 

Comprobar compresión

 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

Desactivarlos y luego reconstruirlos tiene un resultado diferente, ya que la desactivación elimina el índice, mientras se mantiene la definición del índice.

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

Resultado

name    data_compression_desc

Se perdió la compresión, la definición de compresión también se perdería al soltar y crear el índice a través de SSMS sin adaptar el script de creación de índice.

¿Por qué?

Debido a que la opción de compresión de datos no se retiene cuando se crea un script para la instrucción de creación de índice.

sin embargo, si deshabilitamos el índice, reconstruimos con compresión y luego reconstruimos nuevamente:

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

Probar una reconstrucción con la solución de mantenimiento de Ola hallengren

Los parámetros se modifican con fines de prueba.

Agregue algunos datos para llegar a una página, ya que son necesarios para el parámetro MinNumberOfPages.

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

Ejecute el proceso de optimización de índice para imprimir la declaración.

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

Ejecutando el comando generado

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

La compresión se retiene

name    data_compression_desc
IX1 PAGE

Probar una reconstrucción con un plan de mantenimiento (argumentaría firmemente por la solución de ola)

Reconstruir índices

ingrese la descripción de la imagen aquí

Elige la mesa de prueba

ingrese la descripción de la imagen aquí

Agregue algunos niveles de fragmentación de prueba.

ingrese la descripción de la imagen aquí

Inserte algunos valores para que la fragmentación continúe

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

Verificar el porcentaje de fragmentación

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

Ejecuta el plan

ingrese la descripción de la imagen aquí

La parte interesante aquí, al mirar el informe del plan, es que la DATA_COMPRESSION = PAGEopción se agrega al REBUILDcomando generado .

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)

Fragmentación:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2

Compresión:

name    data_compression_desc
IX1 PAGE
Randi Vertongen
fuente
Me encontré con tu publicación cuando descubrí que 3 bases de datos que había comprimido habían perdido su compresión y tuve que volver a aplicarla. Como parte de ese trabajo, probé y confirme sus resultados, pero no tengo idea de cómo sucedió esto. La única otra posibilidad que he encontrado es que, si los índices están deshabilitados, pierden compresión cuando se reconstruyen. Este no parece ser el caso, según nuestro equipo de ETL. También he planteado esta pregunta en SQLServerCentral: sqlservercentral.com/Forums/2017336/Databases-Lost-Compression Totalmente perdido por cómo sucedió esto.
Marvel
Hola @Marvel, ¿podría ser que algún otro proceso recreó índices en las bases de datos? Por ejemplo, algunas aplicaciones hacen 'actualizaciones' donde caen y crean innumerables índices. Sin embargo, no creo que nadie pueda dar una explicación clara sin más detalles. La próxima vez que ocurra, puede encontrar la fecha de creación del índice y si se recrearon (por ejemplo, con la consulta en este enlace: stackoverflow.com/questions/7579932/… . De lo contrario, siempre podría hacer una pregunta, pero yo sí cree que necesitaría proporcionar más información.
Randi Vertongen
1
Gracias Randi! Configuré la auditoría SCHEMA_OBJECT_CHANGE_GROUP en las bases de datos, pero esto definitivamente me ayudará a analizar los registros más rápido. Ya he encontrado a uno de los culpables: el propietario de las bases de datos, el que solicitó la compresión, ha estado modificando tablas e índices constantemente. No se dio cuenta de que cuando creaba nuevas tablas y movía los datos antiguos y creaba nuevos índices, se perdería la compresión. :( Le he proporcionado la forma correcta de crear sus tablas e índices. Sin embargo, no creo que sea el único culpable. No puedo imaginar que haya hecho esto para e
Marvel