Implementação da compactação de linhas

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada de SQL do Azure

Este artigo resume como o Database Engine implementa a compactação de linhas. Este resumo fornece informações básicas para ajudar no planejamento do espaço de armazenamento exigido pelos dados.

A habilitação da compactação altera somente o formato de armazenamento físico dos dados associados a um tipo de dados, mas não sua sintaxe ou semântica. Não são necessárias alterações no aplicativo quando uma ou mais tabelas estão habilitadas para compactação. O novo formato de armazenamento de registros apresenta estas alterações principais:

  • Reduz a sobrecarga de metadados associados ao registro. Esses metadados são informações sobre colunas, seus comprimentos e deslocamentos. Em alguns casos, a sobrecarga de metadados pode ser maior do que o formato de armazenamento antigo.

  • Usa o formato de armazenamento de comprimento variável para tipos numéricos (por exemplo, integer, decimale float) e os tipos baseados em números (por exemplo, datetime e money).

  • Armazena cadeias de caracteres fixas usando o formato de comprimento variável ao não armazenar caracteres em branco.

Observação

Valores NULL e 0 de todos os tipos de dados são otimizados e não ocupam bytes.

Como a compactação de linhas afeta o armazenamento

A tabela a seguir descreve como a compactação de linha afeta os tipos existentes no SQL Server e no Banco de Dados SQL do Azure. A tabela não inclui a economia que pode ser obtida com o uso da compactação de página.

Tipo de dados O armazenamento é afetado? Descrição
tinyint Não 1 byte é o armazenamento mínimo necessário.
smallint Sim Se o valor couber em 1 byte, apenas 1 byte será usado.
int Sim Usa apenas os bytes necessários. Por exemplo, se um valor puder ser armazenado em 1 byte, o armazenamento ocupará apenas 1 byte.
bigint Sim Usa apenas os bytes necessários. Por exemplo, se um valor puder ser armazenado em 1 byte, o armazenamento ocupará apenas 1 byte.
decimal Sim Usa somente os bytes que são necessários, independentemente da precisão especificada. Por exemplo, se um valor puder ser armazenado em 3 bytes, o armazenamento ocupará apenas 3 bytes. O volume de armazenamento é exatamente o mesmo que o formato de armazenamento vardecimal.
numeric Sim Usa somente os bytes que são necessários, independentemente da precisão especificada. Por exemplo, se um valor puder ser armazenado em 3 bytes, o armazenamento ocupará apenas 3 bytes. O volume de armazenamento é exatamente o mesmo que o formato de armazenamento vardecimal.
bit Sim A sobrecarga dos metadados atinge 4 bits.
smallmoney Sim Usa a representação de dados de número inteiro usando um número inteiro de 4 bytes. O valor de moeda é multiplicado por 10.000, e o valor de inteiro resultante é armazenado removendo os dígitos após a vírgula decimal. Esse tipo tem uma otimização de armazenamento semelhante à empregada para tipos de número inteiro.
money Sim Usa a representação de dados de número inteiro usando um número inteiro de 8 bytes. O valor de moeda é multiplicado por 10.000, e o valor de inteiro resultante é armazenado removendo os dígitos após a vírgula decimal. Esse tipo tem um intervalo maior que smallmoney. Esse tipo tem uma otimização de armazenamento semelhante à empregada para tipos de número inteiro.
float Sim Bytes menos significantes com zeros não são armazenados. A compactaçãofloat é aplicável principalmente a valores não fracionários em mantissa.
real Sim Bytes menos significantes com zeros não são armazenados. A compactaçãoreal é aplicável principalmente a valores não fracionários em mantissa.
smalldatetime Não Usa a representação de dados de número inteiro usando números inteiros de 2 bytes e é o número de dias desde 1900-01-01. Não há benefício de compactação de linha para a parte de data de smalldatetime.

A hora é o número de minutos a partir da meia-noite. Os valores de hora logo após 4h começam a usar o segundo byte.

Se um smalldatetime for usado apenas para representar uma data (um caso comum), a hora será 0.0. A compactação salva 2 bytes armazenando a hora em um formato de byte mais significativo para compactação de linha.
datetime Sim Usa a representação de dados de número inteiro usando números inteiros de 4 bytes. O valor de inteiro representa o número de dias com a data base de 1900-01-01. Os primeiros 2 bytes podem representar até o ano 2079. A compactação sempre pode salvar 2 bytes aqui até esse ponto. Cada valor de inteiro representa 3,33 milissegundos. A compactação esvazia os primeiros 2 bytes nos primeiros cinco minutos e precisa do quarto byte após às 16h. Portanto, a compactação pode salvar apenas 1 byte depois das 16h. Quando datetime é compactado como qualquer outro inteiro, a compactação salva 2 bytes na data.
date Não Usa a representação de dados inteiros com 3 bytes. Isso representa a data a partir de 0001-01-01. Para datas contemporâneas, a compactação de linha usa todos os 3 bytes. Não gera nenhum aumento.
time Não Usa a representação de dados inteiros com 3 a 6 bytes. Há várias precisões que começam com 0 a 9 e que podem ocupar de 3 a 6 bytes. O espaço compactado é usado como segue:

Precisão = 0. Bytes = 3. Cada valor de inteiro representa um segundo. A compactação pode representar a hora até 16h usando 2 bytes, salvando potencialmente 1 byte.

Precisão = 1. Bytes = 3. Cada valor de inteiro representa 1/10 segundos. A compactação usa o terceiro byte antes das 2h. Resulta em um pequeno aumento.

Precisão = 2. Bytes = 3. Da mesma forma que no caso anterior, é improvável que haja economia.

Precisão = 3. Bytes = 4. Como os primeiros 3 bytes são usados até as 5h, essa opção gera pouca economia.

Precisão = 4. Bytes = 4. Os primeiros 3 bytes são ocupados nos primeiros 27 segundos. Nenhum aumento é esperado.

Precisão = 5, Bytes = 5. O quinto byte será usado após o meio-dia.

Precisão = 6 e 7, Bytes = 5. Não gera nenhum aumento.

Precisão = 8, Bytes = 6. O sexto byte será usado após as 3h.

Não há alteração no armazenamento para compactação de linhas. De modo geral, não se pode esperar muito aumento da compactação do tipo de dados time .
datetime2 Sim Usa a representação de dados inteiros com 6 a 9 bytes. Os primeiros 4 bytes representam a data. Os bytes usados pelo tempo dependem da precisão do tempo especificado.

O valor de inteiro representa o número de dias desde 0001-01-01 com um limite superior de 31/12/9999. Para representar uma data no ano de 2005, a compactação requer 3 bytes.

Não há economia de tempo porque ele permite de 2 a 4 bytes para várias precisões de tempo. Portanto, para precisão de um segundo, a compactação usa 2 bytes para a hora, que ocupa o segundo byte depois de 255 segundos.
datetimeoffset Sim Assemelha-se a datetime2, exceto pelo fato de que há 2 bytes de fuso horário no formato (HH:mm).

Como datetime2, a compactação pode salvar 2 bytes.

Para valores de fuso horário, o valor mm pode ser 0 na maioria dos casos. Portanto, a compactação pode salvar possivelmente 1 byte.

Não há alteração alguma no armazenamento para compactação de linha.
char Sim Caracteres de preenchimento à direita são removidos. Observe que o Mecanismo de Banco de Dados insere o mesmo caractere de preenchimento, independentemente da ordenação usada.
varchar Não Nenhum efeito.
text Não Nenhum efeito.
nchar Sim 1 Caracteres de preenchimento à direita são removidos. Observe que o Mecanismo de Banco de Dados insere o mesmo caractere de preenchimento, independentemente da ordenação usada.
nvarchar Não 1 Nenhum efeito.
ntext Não Nenhum efeito.
binary Sim Zeros à direita são removidos.
varbinary Não Nenhum efeito.
imagem Não Nenhum efeito.
cursor Não Nenhum efeito.
timestamp / rowversion Sim Usa a representação de dados inteiros com 8 bytes. Há um contador de carimbo de data/hora mantido para cada banco de dados e seu valor começa em 0. Ele pode ser compactado como qualquer outro valor de inteiro.
sql_variant Não Nenhum efeito.
uniqueidentifier Não Nenhum efeito.
table Não Nenhum efeito.
xml Não 2 Nenhum efeito.
Tipos definidos pelo usuário Não É representado internamente como varbinary.
FILESTREAM Não É representado internamente como varbinary.

1 A compactação Unicode é compatível com os tipos de dados de comprimento fixo nchar e nvarchar. Os valores de dados que são armazenados fora da linha ou em colunas nvarchar(max) não são compactados. A Compactação de Unicode não tem suporte para obter dados nvarchar(max) mesmo se forem armazenados em linha.

2 Dados fora da linha não são compactados ao habilitar a compactação de dados. Por exemplo, um registro XML com mais de 8060 bytes usa páginas fora da linha, que não são compactadas.