Gli indici compressi di SQL Server rimangono compressi al momento della ricostruzione senza specificare la compressione dei dati?


13

Dopo aver ricostruito gli indici di SQL Server utilizzando la compressione della pagina ( ALTER INDEX IX1 REBUILD PARTITION = ALL WITH (DATA_COMPRESSION = PAGE)), le ricostruzioni successive (come fatto da alcuni script di manutenzione oltre una determinata soglia di frammentazione) devono specificare nuovamente la compressione dei dati? Gli indici sarebbero altrimenti decompressi in modo efficace?

Risposte:


22

Gli indici rimangono compressi durante la ricostruzione / riorganizzazione.

Crea tabella e indice compresso

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

Controlla la compressione

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

Risultato

name    data_compression_desc
IX1     PAGE

Ricreare l'indice

ALTER INDEX IX1 on  DBO.TEST_INDX rebuild 

Controlla la compressione

 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'

Risultato

name    data_compression_desc
IX1     PAGE

Disabilitarli e quindi ricostruire ha un risultato diverso, poiché la disabilitazione rimuove l'indice, mantenendo la definizione dell'indice.

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

Risultato

name    data_compression_desc

La compressione è stata persa, la definizione di compressione andrebbe persa anche quando si rilasciava e si creava l'indice tramite SSMS senza adattare lo script di creazione dell'indice.

Perché?

Perché l'opzione data_compression non viene mantenuta quando si esegue lo scripting dell'istruzione di creazione dell'indice.

tuttavia, se disabilitiamo l'indice, ricostruiamo con compressione e quindi ricostruiamo di nuovo:

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;

Risultato

name    data_compression_desc
IX1 PAGE

Test di una ricostruzione con la soluzione di manutenzione di Ola hallengren

I parametri vengono modificati a scopo di test.

Aggiungi alcuni dati per arrivare a una pagina, in quanto è necessario per il parametro MinNumberOfPages.

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

Eseguire proc procedi all'indice per stampare l'istruzione.

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;

Risultato:

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

Esecuzione del comando generato

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

La compressione viene mantenuta

name    data_compression_desc
IX1 PAGE

Testare una ricostruzione con un piano di manutenzione (direi fortemente per la soluzione di ola)

Ricostruisci gli indici

inserisci qui la descrizione dell'immagine

Scegli la tabella dei test

inserisci qui la descrizione dell'immagine

Aggiungi alcuni livelli di frammentazione del test.

inserisci qui la descrizione dell'immagine

Inserisci alcuni valori per avviare la frammentazione

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

Controlla la percentuale di frammentazione

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'

Risultato

INDX    avg_fragmentation_in_percent    page_count
IX1 66,6666666666667    3

Esegui il piano

inserisci qui la descrizione dell'immagine

La parte interessante qui, quando si guarda il rapporto del piano, è che l' DATA_COMPRESSION = PAGEopzione viene aggiunta al REBUILDcomando generato !

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)

frammentazione:

INDX    avg_fragmentation_in_percent    page_count
IX1 0   2

Compressione:

name    data_compression_desc
IX1 PAGE

Mi sono imbattuto nel tuo post quando ho scoperto che 3 database che avevo compresso avevano perso tutti la loro compressione e ho dovuto riapplicarlo. Come parte di quel lavoro, ho testato e confermato i tuoi risultati ma non ho idea di come sia successo. L'unica altra possibilità che ho riscontrato è che, se gli indici sono disabilitati, perdono la compressione quando vengono ricostruiti. Questo non sembra essere il caso, per il nostro team ETL. Ho anche posto questa domanda su SQLServerCentral: sqlservercentral.com/Forums/2017336/D Database- Lost - Compression Totalmente in perdita per come è successo.
Marvel,

Ciao @Marvel, potrebbe essere che qualche altro processo abbia ricreato gli indici sui database? Ad esempio, alcune applicazioni eseguono "aggiornamenti" laddove rilasciano e creano innumerevoli indici. Tuttavia, non credo che nessuno sarà in grado di fornire una spiegazione chiara senza ulteriori dettagli. La prossima volta, potresti trovare la data di creazione dell'indice e scoprire se sono stati ricreati (ad es. Con la query in questo link: stackoverflow.com/questions/7579932/… . Altrimenti potresti sempre fare una domanda, ma lo faccio pensa che dovresti fornire maggiori informazioni.
Randi Vertongen,

1
Grazie Randi! Ho impostato il controllo SCHEMA_OBJECT_CHANGE_GROUP sui database ma questo mi aiuterà sicuramente ad analizzare i registri più velocemente. Ho già trovato uno dei colpevoli, il proprietario dei database, quello che ha richiesto la compressione ha modificato costantemente tabelle e indici. Non si rese conto che quando creava nuove tabelle e spostava i vecchi dati e creava nuovi indici, la compressione andava persa. :( Non gli ho fornito il modo corretto di creare tabelle e indici. Non credo che sia l'unico colpevole, tuttavia. Non posso immaginare di averlo fatto per e
Marvel il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.