Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Estimar a economia de compactação de dados no SQL Server


O SQL Server tem um procedimento armazenado do sistema chamado sp_estimate_data_compression_savings , que permite verificar o tamanho de um objeto e seu tamanho estimado com vários níveis de compactação.

Se o objeto já estiver compactado, você pode usar este procedimento para estimar seu tamanho quando compactado novamente.

Os objetos podem ser compactados usando compactação de arquivo de linha, página, columnstore ou columnstore.

A compactação pode ser avaliada para tabelas inteiras ou partes de tabelas. Isso inclui heaps, índices clusterizados, índices não clusterizados, índices columnstore, exibições indexadas e partições de tabela e índice.

Exemplo


Aqui está um exemplo para demonstrar.
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 você tenha que fazer muita rolagem lateral, aqui está novamente usando a saída 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

Os tamanhos de compactação estão em kilobytes (KB).

Nesse caso, parece haver um benefício significativo em usar a compactação de linha nesta tabela. Vai de 32 KB a 8 KB. Isso pressupõe que é uma estimativa precisa.

Quando executei o código anterior, forneci todos os nomes de argumentos. Você também pode omitir esses nomes e apenas fornecer os valores.

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

De qualquer forma, o resultado é o mesmo.

Aqui está novamente, mas desta vez eu especifico PAGE em vez de ROW como o tipo de compressão.
EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemHoldings', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'PAGE';

Resultado (usando saída 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

Nesse caso, os números parecem os mesmos, mas você pode obter números muito diferentes, dependendo dos seus dados.

Tipos de compactação


O @data_compression argumento aceita os seguintes valores:
  • NENHUM
  • ROW
  • PÁGINA
  • COLUMNSTORE
  • COLUMNSTORE_ARCHIVE

Estas são as opções de compactação disponíveis ao criar/alterar uma tabela ou índice.

A COLUMNSTORE e COLUMNSTORE_ARCHIVE as opções estão disponíveis apenas em índices columnstore (incluindo índices columnstore não clusterizados e columnstore clusterizados).

O @index_id Argumento


Às vezes, seus resultados podem retornar várias linhas para um determinado objeto, cada uma com um index_id diferente .

Você pode reduzi-lo a um índice específico, se preferir. Para fazer isso, forneça o index_id para o @index_id argumento.

Por exemplo, quando executo o código a seguir, oito linhas são retornadas, cada uma com index_id diferente 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                                                 |
+-----------------------+---------------+------------+--------------------+---------------------------------------------+-----------------------------------------------+----------------------------------------------------+------------------------------------------------------+

Se quiséssemos reduzi-lo a apenas uma linha, poderíamos usar seu index_id .

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

Você também pode usar @partition_number fazer a mesma coisa com partições.

A quantidade de compactação pode variar significativamente


A quantidade de compactação obtida dependerá dos dados e do tipo de compactação.

ROW a compactação, por exemplo, remove bytes desnecessários dos valores da coluna armazenando-os em formato de comprimento variável. PÁGINA a compressão, por outro lado, armazena os valores repetidos apenas uma vez por página e define o ponteiro das respectivas colunas dentro da página.

Às vezes, você pode descobrir que compactar um objeto nem sempre diminui seu tamanho e, em alguns casos, pode aumentar seu tamanho.

Isso pode acontecer se suas colunas usarem um tipo de dados que não se beneficie da compactação.

Além disso, a compactação de linha reduz a sobrecarga de metadados, mas em alguns casos a sobrecarga pode ser maior do que o formato de armazenamento antigo.

Se seus dados não receberem nenhum benefício da compactação devido ao seu tipo de dados, é provável que a sobrecarga cause um aumento nos requisitos de armazenamento, em vez de uma diminuição.

Mas as variações no tamanho da compactação também dependerão dos dados reais. Por exemplo, se você tiver um char(10) coluna, a compactação removerá quaisquer caracteres de preenchimento à direita. Se você tiver muitas linhas com caracteres de preenchimento à direita, deverá obter um resultado melhor do que se não tiver nenhuma (ou poucas) linhas com caracteres de preenchimento à direita.

Como ele estima a compactação?


Quando você executa sp_estimate_data_compression_savings , ele pega uma amostra dos dados e os carrega em uma tabela e índice equivalentes criados em tempdb . A tabela ou índice criado em tempdb é então compactado para a configuração solicitada e as economias de compactação estimadas são calculadas.

Qual ​​é a precisão?


Você pode obter resultados mistos ao usar sp_estimate_data_compression_savings .

Vamos fazer um pequeno teste.
SELECT * INTO Warehouse.StockItemTransactions2
FROM Warehouse.StockItemTransactions;

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Resultado (usando saída vertical):
name       | StockItemTransactions2
rows       | 236667              
reserved   | 15944 KB
data       | 15800 KB
index_size | 8 KB
unused     | 136 KB

O sp_spaceusado procedimento armazenado nos mostra o espaço em disco real usado. Nesse caso, os dados usam 15.800 KB de espaço em disco.

Agora, executarei sp_estimate_data_compression_savings para ver que economia de espaço obterei se aplicar compactação a essa tabela.
EXEC sp_estimate_data_compression_savings 
    @schema_name = 'Warehouse', 
    @object_name = 'StockItemTransactions2', 
    @index_id = NULL, 
    @partition_number = NULL, 
    @data_compression = 'ROW';

Resultado (usando saída 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 acordo com esses resultados, aplicar a compactação de linha a essa tabela reduzirá seu tamanho de 15.808 KB para um tamanho estimado de apenas 9.096 KB. Não é tão ruim.

Vamos agora aplicar a compactação de linha a esta tabela e, em seguida, executar sp_spaceused novamente.
ALTER TABLE Warehouse.StockItemTransactions2
REBUILD WITH (DATA_COMPRESSION = ROW);

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Resultado (usando saída vertical):
name       | StockItemTransactions2
rows       | 236667              
reserved   | 9160 KB
data       | 9088 KB
index_size | 8 KB

Portanto, o resultado real está muito próximo do resultado estimado.

Nesse caso, sp_estimate_data_compression_savings forneceu uma estimativa bastante precisa do resultado final.

Vamos executar sp_estimate_data_compression_savings mais uma vez, mas usando um tipo de compressão 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

Isso nos diz o que aconteceria se voltássemos a usar nenhuma compactação.

Nesse caso, está nos mostrando exatamente o mesmo número (15.808 KB) que nos mostrou antes de aplicar a compactação que, como você deve se lembrar, era bem próximo do tamanho real (15.800 KB) retornado pelo sp_spaceused procedimento.

Então, vamos executá-lo novamente e descobrir.
ALTER TABLE Warehouse.StockItemTransactions2
REBUILD WITH (DATA_COMPRESSION = NONE);

EXEC sp_spaceused 'Warehouse.StockItemTransactions2';

Resultado (usando saída vertical):
name       | StockItemTransactions2
rows       | 236667              
reserved   | 15880 KB
data       | 15800 KB
index_size | 8 KB
unused     | 72 KB

Então, novamente, sp_estimate_data_compression_savings estava quase no local.

No entanto, este é apenas um teste simples. Outros testes podem retornar estimativas muito distantes. Li histórias de sp_estimate_data_compression_savings retornando resultados extremamente imprecisos, mas ainda não experimentei isso.

Portanto, parece que sp_estimate_data_compression_savings pode fornecer uma estimativa precisa nos mesmos casos, e não tanto em outros.

Você precisará decidir quanta confiança deseja colocar nesse procedimento armazenado. De qualquer forma, você provavelmente deve executar um teste em seu ambiente de desenvolvimento ou teste antes de aplicar a compactação na produção.