Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Estimer les économies de compression de données dans SQL Server

SQL Server a une procédure stockée système appelée sp_estimate_data_compression_savings , qui vous permet de vérifier la taille d'un objet et sa taille estimée avec différents niveaux de compression.

Si l'objet est déjà compressé, vous pouvez utiliser cette procédure pour estimer sa taille une fois recompressé.

Les objets peuvent être compressés à l'aide de la compression d'archive de ligne, de page, de magasin de colonnes ou de magasin de colonnes.

La compression peut être évaluée pour des tables entières ou des parties de tables. Cela inclut les tas, les index clusterisés, les index non clusterisés, les index columnstore, les vues indexées et les partitions de table et d'index.

Exemple

Voici un exemple pour illustrer.

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

Résultat :

+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| 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                                                   |
+-------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Pour vous éviter d'avoir à faire trop de défilement latéral, le voici à nouveau en utilisant la sortie 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

Les tailles de compression sont en kilo-octets (Ko).

Dans ce cas, il semble y avoir un avantage significatif à utiliser la compression de ligne sur cette table. Il passe de 32 Ko à 8 Ko. Cela suppose qu'il s'agit d'une estimation précise.

Lorsque j'ai exécuté le code précédent, j'ai fourni tous les noms d'arguments. Vous pouvez également omettre ces noms et fournir uniquement les valeurs.

Comme ceci :

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

Dans tous les cas, le résultat est le même.

Le revoici, mais cette fois je précise PAGE au lieu de ROW comme type de compression.

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

Résultat (en utilisant la sortie 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

Dans ce cas, les chiffres semblent identiques, mais vous pouvez obtenir des chiffres très différents, en fonction de vos données.

Types de compression

Le @data_compression l'argument accepte les valeurs suivantes :

  • NONE
  • ROW
  • PAGE
  • COLUMNSTORE
  • COLUMNSTORE_ARCHIVE

Voici les options de compression disponibles lors de la création/modification d'une table ou d'un index.

Le COLUMNSTORE et COLUMNSTORE_ARCHIVE les options ne sont disponibles que sur les index columnstore (y compris les index columnstore non clusterisés et clusterisés).

Le @index_id Argumentation

Parfois, vos résultats peuvent renvoyer plusieurs lignes pour un objet donné, chacune avec un index_id différent .

Vous pouvez le réduire à un index spécifique si vous préférez. Pour ce faire, fournissez le index_id au @index_id arguments.

Par exemple, lorsque j'exécute le code suivant, huit lignes sont renvoyées, chacune avec un index_id différent valeurs.

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

Résultat :

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| 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                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Si nous voulions le réduire à une seule ligne, nous pourrions utiliser son index_id .

Comme ceci :

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

Résultat :

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| 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                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Vous pouvez également utiliser @partition_number faire la même chose avec les partitions.

La quantité de compression peut varier considérablement

La quantité de compression obtenue dépendra des données et du type de compression.

ROW la compression, par exemple, supprime les octets inutiles des valeurs de colonne en les stockant dans un format de longueur variable. PAGE la compression, en revanche, stocke les valeurs répétées une seule fois par page et définit le pointeur à partir des colonnes respectives de la page.

Parfois, vous pouvez constater que la compression d'un objet ne diminue pas toujours sa taille et, dans certains cas, peut en fait augmenter sa taille.

Cela peut se produire si vos colonnes utilisent un type de données qui ne bénéficie pas de la compression.

En outre, la compression des lignes réduit la surcharge des métadonnées, mais dans certains cas, la surcharge peut être supérieure à l'ancien format de stockage.

Si vos données ne bénéficient pas de la compression en raison de leur type de données, il est probable que la surcharge entraînera une augmentation des besoins de stockage, plutôt qu'une diminution.

Mais les variations de la taille de compression dépendront également des données réelles. Par exemple, si vous avez un char(10) colonne, la compression supprimera tous les caractères de remplissage de fin. Si vous avez beaucoup de lignes avec des caractères de remplissage à la fin, vous devriez obtenir un meilleur résultat que si vous n'avez pas (ou peu) de lignes avec des caractères de remplissage à la fin.

Comment estime-t-il la compression ?

Lorsque vous exécutez sp_estimate_data_compression_savings , il prend un échantillon des données, puis le charge dans une table et un index équivalents créés dans tempdb . La table ou l'index créé dans tempdb est ensuite compressé au paramètre demandé et les économies de compression estimées sont calculées.

Quelle est la précision ?

Vous pouvez obtenir des résultats mitigés lorsque vous utilisez sp_estimate_data_compression_savings .

Faisons un petit test.

SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Résultat (en utilisant la sortie verticale) :

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

Le sp_spaceused procédure stockée nous montre l'espace disque réel utilisé. Dans ce cas, les données utilisent 15 800 Ko d'espace disque.

Maintenant, je vais exécuter sp_estimate_data_compression_savings pour voir les économies d'espace que j'obtiendrai si j'applique la compression à cette table.

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

Résultat (en utilisant la sortie 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

Selon ces résultats, l'application de la compression de lignes à cette table réduira sa taille de 15 808 Ko à une taille estimée de seulement 9 096 Ko. Pas trop mal.

Appliquons maintenant la compression de ligne à cette table, puis exécutons sp_spaceused à nouveau.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Résultat (en utilisant la sortie verticale) :

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

Le résultat réel est donc très proche du résultat estimé.

Dans ce cas, sp_estimate_data_compression_savings fourni une estimation assez précise du résultat final.

Exécutons sp_estimate_data_compression_savings une fois de plus, mais en utilisant un type de compression de NONE .

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

Résultat :

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

Cela nous indique ce qui se passerait si nous revenions à l'absence de compression.

Dans ce cas, il nous montre exactement le même nombre (15 808 Ko) qu'il nous a montré avant d'appliquer la compression qui, comme vous vous en souviendrez, était assez proche de la taille réelle (15 800 Ko) renvoyée par le sp_spaceused procédure.

Alors réexécutons-le et découvrons-le.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Résultat (en utilisant la sortie verticale) :

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

Encore une fois, sp_estimate_data_compression_savings était presque parfait.

Cependant, ce n'est qu'un test simple. D'autres tests pourraient renvoyer des estimations très éloignées. J'ai lu des histoires de sp_estimate_data_compression_savings renvoyer des résultats extrêmement inexacts, mais je n'en ai pas encore fait l'expérience moi-même.

Par conséquent, il semblerait que sp_estimate_data_compression_savings peut fournir une estimation précise dans les mêmes cas, et pas tellement dans d'autres.

Vous devrez décider de la confiance que vous souhaitez accorder à cette procédure stockée. Dans tous les cas, vous devriez probablement exécuter un test dans votre environnement de développement ou de test avant d'appliquer la compression en production.