sql >> Base de Datos >  >> RDS >> Sqlserver

Calcule los ahorros de compresión de datos en SQL Server

SQL Server tiene un procedimiento almacenado del sistema llamado sp_estimate_data_compression_savings , que le permite verificar el tamaño de un objeto y su tamaño estimado con varios niveles de compresión.

Si el objeto ya está comprimido, puede usar este procedimiento para estimar su tamaño cuando se vuelva a comprimir.

Los objetos se pueden comprimir mediante la compresión de filas, páginas, almacenes de columnas o archivos de almacén de columnas.

La compresión se puede evaluar para tablas completas o partes de tablas. Esto incluye montones, índices agrupados, índices no agrupados, índices de almacén de columnas, vistas indexadas y particiones de tablas e índices.

Ejemplo

Aquí hay un ejemplo para demostrarlo.

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

Resultado:

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

Para evitar que tenga que desplazarse demasiado hacia los lados, aquí está de nuevo usando la salida vertical:

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

Los tamaños de compresión están en kilobytes (KB).

En este caso, parece haber un beneficio significativo al usar la compresión de filas en esta tabla. Va de 32 KB a 8 KB. Esto supone que es una estimación precisa.

Cuando ejecuté el código anterior, proporcioné todos los nombres de los argumentos. También puede omitir estos nombres y solo proporcionar los valores.

Así:

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

De cualquier manera, el resultado es el mismo.

Aquí está de nuevo, pero esta vez especifico PAGE en lugar de ROW como el tipo de compresión.

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

Resultado (usando salida vertical):

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

En este caso, los números se ven iguales, pero podría obtener números muy diferentes, según sus datos.

Tipos de compresión

El @data_compression argumento acepta los siguientes valores:

  • NONE
  • ROW
  • PAGE
  • COLUMNSTORE
  • COLUMNSTORE_ARCHIVE

Estas son las opciones de compresión disponibles al crear/modificar una tabla o índice.

El COLUMNSTORE y COLUMNSTORE_ARCHIVE Las opciones solo están disponibles en los índices de almacén de columnas (incluidos los índices de almacén de columnas no agrupados y agrupados).

El @index_id Argumento

A veces, los resultados pueden devolver varias filas para un objeto determinado, cada una con un index_id diferente. .

Puede reducirlo a un índice específico si lo prefiere. Para hacer esto, proporcione el index_id al @index_id argumento.

Por ejemplo, cuando ejecuto el siguiente código, se devuelven ocho filas, cada una con diferente index_id valores.

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

Resultado:

+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+
| 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 quisiéramos reducirlo a una sola fila, podríamos usar su index_id .

Así:

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

Resultado:

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

También puede usar @partition_number hacer lo mismo con las particiones.

La cantidad de compresión puede variar significativamente

La cantidad de compresión que obtenga dependerá de los datos y del tipo de compresión.

ROW la compresión, por ejemplo, elimina los bytes innecesarios de los valores de la columna almacenándolos en un formato de longitud variable. PAGE la compresión, por otro lado, almacena los valores repetidos solo una vez por página y establece el puntero desde las columnas respectivas dentro de la página.

A veces, puede encontrar que comprimir un objeto no siempre reduce su tamaño y, en algunos casos, en realidad podría aumentar. su tamaño.

Esto podría suceder si sus columnas usan un tipo de datos que no se beneficia de la compresión.

Además, la compresión de filas reduce la sobrecarga de metadatos, pero en algunos casos la sobrecarga puede ser mayor que el formato de almacenamiento anterior.

Si sus datos no se benefician de la compresión debido a su tipo de datos, es probable que la sobrecarga provoque un aumento en los requisitos de almacenamiento, en lugar de una disminución.

Pero las variaciones en el tamaño de la compresión también dependerán de los datos reales. Por ejemplo, si tiene un char(10) columna, la compresión eliminará cualquier carácter de relleno final. Si tiene muchas filas con caracteres de relleno al final, debería obtener un mejor resultado que si no tiene (o tiene pocas) filas con caracteres de relleno al final.

¿Cómo estima la compresión?

Cuando ejecuta sp_estimate_data_compression_savings , toma una muestra de los datos y luego los carga en una tabla y un índice equivalentes creados en tempdb . La tabla o índice creado en tempdb luego se comprime a la configuración solicitada y se calculan los ahorros de compresión estimados.

¿Qué tan preciso es?

Puede obtener resultados mixtos al usar sp_estimate_data_compression_savings .

Hagamos una pequeña prueba.

SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Resultado (usando salida vertical):

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

El sp_spaceused El procedimiento almacenado nos muestra el espacio en disco real utilizado. En este caso, los datos utilizan 15 800 KB de espacio en disco.

Ahora, ejecutaré sp_estimate_data_compression_savings para ver qué ahorro de espacio obtendré si aplico compresión a esa tabla.

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

Resultado (usando salida vertical):

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

De acuerdo con estos resultados, aplicar compresión de filas a esta tabla reducirá su tamaño de 15 808 KB a un tamaño estimado de solo 9096 KB. No está mal.

Apliquemos ahora la compresión de filas a esta tabla y luego ejecutemos sp_spaceused de nuevo.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Resultado (usando salida vertical):

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

Entonces, el resultado real está muy cerca del resultado estimado.

En este caso, sp_estimate_data_compression_savings proporcionó una estimación bastante precisa del resultado final.

Ejecutemos sp_estimate_data_compression_savings una vez más, pero usando un tipo de compresión de NONE .

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

Resultado:

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

Esto nos dice qué pasaría si volviéramos a no usar compresión.

En este caso, nos muestra exactamente el mismo número (15 808 KB) que nos mostró antes de aplicar la compresión que, como recordará, estaba bastante cerca del tamaño real (15 800 KB) devuelto por el sp_spaceused procedimiento.

Así que vamos a ejecutarlo de nuevo y averiguarlo.

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

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Resultado (usando salida vertical):

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

De nuevo, sp_estimate_data_compression_savings casi dio en el clavo.

Sin embargo, esta es solo una prueba simple. Otras pruebas podrían arrojar estimaciones que están muy lejos. He leído historias de sp_estimate_data_compression_savings devolviendo resultados tremendamente inexactos, pero todavía tengo que experimentar eso yo mismo.

Por lo tanto, parecería que sp_estimate_data_compression_savings puede proporcionar una estimación precisa en algunos casos, y no tanto en otros.

Deberá decidir cuánta confianza desea poner en este procedimiento almacenado. En cualquier caso, probablemente debería ejecutar una prueba en su entorno de desarrollo o prueba antes de aplicar la compresión en producción.