web-dev-qa-db-fra.com

Les index compressés SQL Server restent-ils compressés lors de la reconstruction sans spécifier la compression des données?

Après avoir reconstruit leurs index SQL Server à l'aide de la compression de page (ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)), les reconstructions suivantes (comme le font certains scripts de maintenance après un certain seuil de fragmentation) doivent-elles spécifier à nouveau la compression des données? Les indices seraient-ils autrement décompressés efficacement?

14

Les index restent compressés lors de leur reconstruction/réorganisation.

Créer une table et un index compressé

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

Vérifier la compression

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

Résultat

name    data_compression_desc
IX1     PAGE

Reconstruire l'index

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 

Vérifier la compression

 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'

Résultat

name    data_compression_desc
IX1     PAGE

Les désactiver puis les reconstruire ont un résultat différent, car la désactivation supprime l'index, tout en conservant la définition d'index.

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

Résultat

name    data_compression_desc

La compression a été perdue, la définition de la compression serait également perdue lors de la suppression et de la création de l'index via SSMS sans adapter le script de création d'index.

Pourquoi?

Parce que l'option data_compression n'est pas conservée lors du scriptage de l'instruction create index.

cependant, si nous désactivons l'index, reconstruisons avec compression puis reconstruisons à nouveau:

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;

Résultat

name    data_compression_desc
IX1 PAGE

Test d'une reconstruction avec la solution de maintenance d'Ola hallengren

Les paramètres sont modifiés à des fins de test.

Ajoutez des données pour accéder à une page, car elles sont nécessaires pour le paramètre MinNumberOfPages.

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

Exécutez le processus d'optimisation d'index pour imprimer l'instruction.

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;

Résultat:

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

Exécution de la commande générée

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

La compression est conservée

name    data_compression_desc
IX1 PAGE

Test d'une reconstruction avec un plan de maintenance (je plaiderais fortement pour la solution d'ola)

Reconstruire les index

enter image description here

Choisissez la table de test

enter image description here

Ajoutez des niveaux de fragmentation de test.

enter image description here

Insérez quelques valeurs pour lancer la fragmentation

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

Vérifiez le pourcentage de fragmentation

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'

Résultat

INDX    avg_fragmentation_in_percent    page_count
IX1 66,6666666666667    3

Exécutez le plan

enter image description here

La partie intéressante ici, quand on regarde le rapport de plan, est que l'option DATA_COMPRESSION = PAGE Est ajoutée à la commande REBUILD générée!

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)

Fragmentation:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2

Compression:

name    data_compression_desc
IX1 PAGE
23
Randi Vertongen