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.