Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Stima dei risparmi di compressione dei dati in SQL Server

SQL Server dispone di una stored procedure di sistema denominata sp_estimate_data_compression_savings , che ti permette di controllare la dimensione di un oggetto e la sua dimensione stimata con vari livelli di compressione.

Se l'oggetto è già compresso, puoi utilizzare questa procedura per stimarne le dimensioni una volta ricompresso.

Gli oggetti possono essere compressi utilizzando la compressione dell'archivio di righe, pagine, columnstore o columnstore.

La compressione può essere valutata per intere tabelle o parti di tabelle. Ciò include heap, indici cluster, indici non cluster, indici columnstore, viste indicizzate e partizioni di tabelle e indici.

Esempio

Ecco un esempio da dimostrare.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemHoldings', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Risultato:

+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| object_name       | schema_name   | index_id   | partition_number   | size_with_current_compression_setting(KB)   | size_with_requested_compression_setting(KB)   | sample_size_with_current_compression_setting(KB)   | sample_size_with_requested_compression_setting(KB)   |
|-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------|
| StockItemHoldings | Warehouse     | 1          | 1                  | 32                                          | 8                                             | 40                                                 | 16                                                   |
+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Per evitare di dover scorrere troppo lateralmente, eccolo di nuovo utilizzando l'output verticale:

-[ RECORD 1 ]-------------------------
object_name                                        | StockItemHoldings
schema_name                                        | Warehouse
index_id                                           | 1
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 32
size_with_requested_compression_setting(KB)        | 8
sample_size_with_current_compression_setting(KB)   | 40
sample_size_with_requested_compression_setting(KB) | 16

Le dimensioni della compressione sono in kilobyte (KB).

In questo caso, sembra esserci un vantaggio significativo nell'uso della compressione di riga su questa tabella. Va da 32 KB a 8 KB. Ciò presuppone che si tratti di una stima accurata.

Quando ho eseguito il codice precedente, ho fornito tutti i nomi degli argomenti. Puoi anche omettere questi nomi e fornire solo i valori.

In questo modo:

EXEC sp_estimate_data_compression_savings 
    'Warehouse', 
    'StockItemHoldings', 
    NULL, 
    NULL, 
    'ROW';

In ogni caso, il risultato è lo stesso.

Eccolo di nuovo, ma questa volta specifico PAGE invece di ROW come tipo di compressione.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemHoldings', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'PAGE';

Risultato (usando l'output verticale):

-[ RECORD 1 ]-------------------------
object_name                                        | StockItemHoldings
schema_name                                        | Warehouse
index_id                                           | 1
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 32
size_with_requested_compression_setting(KB)        | 8
sample_size_with_current_compression_setting(KB)   | 40
sample_size_with_requested_compression_setting(KB) | 16

In questo caso, i numeri sembrano gli stessi, ma potresti ottenere numeri molto diversi, a seconda dei tuoi dati.

Tipi di compressione

Il @data_compression argomento accetta i seguenti valori:

  • NONE
  • ROW
  • PAGE
  • COLUMNSTORE
  • COLUMNSTORE_ARCHIVE

Queste sono le opzioni di compressione disponibili durante la creazione/modifica di una tabella o di un indice.

Il COLUMNSTORE e COLUMNSTORE_ARCHIVE le opzioni sono disponibili solo negli indici columnstore (compresi sia gli indici columnstore non cluster sia gli indici columnstore cluster).

Il @index_id Argomento

A volte i tuoi risultati potrebbero restituire più righe per un determinato oggetto, ognuna con un diverso index_id .

Puoi restringerlo a un indice specifico, se preferisci. A tale scopo, fornisci l'id_indice al @index_id argomento.

Ad esempio, quando eseguo il codice seguente, vengono restituite otto righe, ciascuna con index_id diverso valori.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Risultato:

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| object_name           | schema_name   | index_id   | partition_number   | size_with_current_compression_setting(KB)   | size_with_requested_compression_setting(KB)   | sample_size_with_current_compression_setting(KB)   | sample_size_with_requested_compression_setting(KB)   |
|-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------|
| StockItemTransactions | Warehouse     | 2          | 1                  | 5568                                        | 4120                                          | 4280                                               | 3168                                                 |
| StockItemTransactions | Warehouse     | 3          | 1                  | 5184                                        | 3720                                          | 4264                                               | 3064                                                 |
| StockItemTransactions | Warehouse     | 4          | 1                  | 5568                                        | 4224                                          | 4288                                               | 3256                                                 |
| StockItemTransactions | Warehouse     | 5          | 1                  | 5528                                        | 4416                                          | 4280                                               | 3424                                                 |
| StockItemTransactions | Warehouse     | 6          | 1                  | 5192                                        | 3456                                          | 4264                                               | 2840                                                 |
| StockItemTransactions | Warehouse     | 7          | 1                  | 5192                                        | 3464                                          | 4264                                               | 2848                                                 |
| StockItemTransactions | Warehouse     | 9          | 1                  | 5416                                        | 4456                                          | 4264                                               | 3512                                                 |
| StockItemTransactions | Warehouse     | 1          | 1                  | 2720                                        | 9096                                          | 2720                                               | 9096                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Se volessimo restringerlo a una sola riga, potremmo utilizzare il suo index_id .

In questo modo:

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions', 
    @index_id =1, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Risultato:

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| object_name           | schema_name   | index_id   | partition_number   | size_with_current_compression_setting(KB)   | size_with_requested_compression_setting(KB)   | sample_size_with_current_compression_setting(KB)   | sample_size_with_requested_compression_setting(KB)   |
|-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------|
| StockItemTransactions | Warehouse     | 1          | 1                  | 2720                                        | 9096                                          | 2720                                               | 9096                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Puoi anche utilizzare @partition_number fare la stessa cosa con le partizioni.

La quantità di compressione può variare in modo significativo

La quantità di compressione che ottieni dipenderà dai dati e dal tipo di compressione.

ROW la compressione, ad esempio, rimuove i byte non necessari dai valori delle colonne archiviandoli in un formato a lunghezza variabile. PAGE la compressione, invece, memorizza i valori ripetuti solo una volta per pagina e imposta il puntatore dalle rispettive colonne all'interno della pagina.

A volte potresti scoprire che la compressione di un oggetto non sempre riduce le sue dimensioni e in alcuni casi potrebbe effettivamente aumentare la sua dimensione.

Ciò potrebbe verificarsi se le colonne utilizzano un tipo di dati che non beneficia della compressione.

Inoltre, la compressione delle righe riduce l'overhead dei metadati, ma in alcuni casi l'overhead potrebbe essere maggiore del vecchio formato di archiviazione.

Se i tuoi dati non ricevono alcun vantaggio dalla compressione a causa del loro tipo di dati, è probabile che l'overhead provochi un aumento dei requisiti di archiviazione, anziché una diminuzione.

Ma le variazioni nelle dimensioni della compressione dipenderanno anche dai dati effettivi. Ad esempio, se hai un char(10) colonna, la compressione rimuoverà tutti i caratteri di riempimento finali. Se hai molte righe con caratteri di riempimento finali, dovresti ottenere un risultato migliore rispetto a se non hai (o poche) righe con caratteri di riempimento finali.

Come stima la compressione?

Quando esegui sp_estimate_data_compression_savings , preleva un campione dei dati, quindi lo carica in una tabella e un indice equivalenti creati in tempdb . La tabella o l'indice creati in tempdb viene quindi compresso all'impostazione richiesta e viene calcolato il risparmio di compressione stimato.

Quanto è preciso?

Potresti ottenere risultati contrastanti usando sp_estimate_data_compression_savings .

Facciamo un piccolo test.

SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Risultato (usando l'output verticale):

name       | StockItemTransactions2
rows       | 236667              
reserved   | 15944 KB
data       | 15800 KB
index_size | 8 KB
unused     | 136 KB

Il sp_spaceused stored procedure ci mostra lo spazio su disco effettivo utilizzato. In questo caso, i dati utilizzano 15.800 KB di spazio su disco.

Ora eseguirò sp_estimate_data_compression_savings per vedere quale risparmio di spazio otterrò se applico la compressione a quella tabella.

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions2', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Risultato (usando l'output verticale):

object_name                                        | StockItemTransactions2
schema_name                                        | Warehouse
index_id                                           | 0
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 15808
size_with_requested_compression_setting(KB)        | 9096
sample_size_with_current_compression_setting(KB)   | 15800
sample_size_with_requested_compression_setting(KB) | 9096

In base a questi risultati, l'applicazione della compressione di riga a questa tabella ridurrà le sue dimensioni da 15.808 KB a una dimensione stimata di soli 9.096 KB. Non male.

Ora applichiamo la compressione di riga a questa tabella, quindi eseguiamo sp_spaceused di nuovo.

ALTER TABLE Warehouse.StockItemTransactions2
REBUILD WITH (DATA_COMPRESSION = ROW);

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Risultato (usando l'output verticale):

name       | StockItemTransactions2
rows       | 236667              
reserved   | 9160 KB
data       | 9088 KB
index_size | 8 KB

Quindi il risultato effettivo è molto vicino al risultato stimato.

In questo caso, sp_estimate_data_compression_savings fornito una stima abbastanza accurata del risultato finale.

Eseguiamo sp_estimate_data_compression_savings ancora una volta, ma utilizzando un tipo di compressione NONE .

EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions2', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'NONE';

Risultato:

object_name                                        | StockItemTransactions2
schema_name                                        | Warehouse
index_id                                           | 0
partition_number                                   | 1
size_with_current_compression_setting(KB)          | 9096
size_with_requested_compression_setting(KB)        | 15808
sample_size_with_current_compression_setting(KB)   | 9096
sample_size_with_requested_compression_setting(KB) | 15808

Questo ci dice cosa accadrebbe se tornassimo a non utilizzare la compressione.

In questo caso ci mostra esattamente lo stesso numero (15.808 KB) che ci mostrava prima di applicare la compressione che, come ricorderete, era abbastanza vicino alla dimensione effettiva (15.800 KB) restituita da sp_spaceused procedura.

Quindi eseguiamolo di nuovo e scopriamolo.

ALTER TABLE Warehouse.StockItemTransactions2
REBUILD WITH (DATA_COMPRESSION = NONE);

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Risultato (usando l'output verticale):

name       | StockItemTransactions2
rows       | 236667              
reserved   | 15880 KB
data       | 15800 KB
index_size | 8 KB
unused     | 72 KB

Quindi, ancora, sp_estimate_data_compression_savings era quasi perfetto.

Tuttavia, questo è solo un semplice test. Altri test potrebbero restituire stime lontane. Ho letto storie di sp_estimate_data_compression_savings restituendo risultati estremamente imprecisi, ma devo ancora sperimentarlo io stesso.

Pertanto, sembrerebbe che sp_estimate_data_compression_savings può fornire una stima accurata negli stessi casi e non tanto negli altri.

Dovrai decidere quanta fiducia vuoi mettere in questa procedura memorizzata. In ogni caso, dovresti probabilmente eseguire un test nel tuo ambiente di sviluppo o test prima di applicare la compressione in produzione.