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.