Maneira alternativa de comprimir NVARCHAR (MAX)?

14

Estou tentando comprimir algumas tabelas que possuem NVARCHAR(MAX)campos. Infelizmente, o roweo pagede compressão não tem o impacto desejo (apenas ~ 100/200 MB guardado para 20 mesa GB). Além disso, não consigo aplicar as compressões de arquivamento de armazenamento de colunas e armazenamento de colunas porque elas não oferecem suporte à compactação de NVARCHAR(MAX)campos.

Alguém pode dizer se eu tenho alguma alternativa aqui?

Eu também acho que a compressão rowe pagenão tem efeito porque o conteúdo das NVARCHAR(MAX)colunas é único.

gotqn
fonte
2
Os valores da coluna são definitivamente maiores que 8000 caracteres? por exemplo, SELECT MAX (CAST (LEN (widecolumn) AS BIGINT)) FROM dbo.largeTable Caso contrário, você poderá convertê-los em varchar comum e aplicar columnstore clusterizado.
wBob
@wBob Mesmo se o maior valor fosse de apenas 2.000 caracteres, a conversão não VARCHARcausaria perda de dados se os caracteres de mais de uma página de código estivessem sendo usados? Eu acho que o conselho deve ser converter para NVARCHAR(4000)se o comprimento máximo não for maior que 4000, porque todos os valores seriam elegíveis para a compactação Unicode completa. Ainda assim, provavelmente é seguro supor pelas informações da pergunta que os valores têm mais de 4000 caracteres, e é por isso que eles não estão compactando no momento.
Solomon Rutzky 18/04/19

Respostas:

16

A compactação de página e linha não compacta BLOBs .

Devido ao seu tamanho, às vezes os tipos de dados de grande valor são armazenados separadamente dos dados de linha normais nas páginas de finalidades especiais. A compactação de dados não está disponível para os dados armazenados separadamente.

Se você deseja compactar BLOBs, é necessário armazená-los como VARBINARY(MAX) e aplicar o algoritmo de compactação de fluxo escolhido. Por exemplo GZipStream. Existem muitos exemplos de como fazer isso, basta procurar por GZipStream e SQLCLR.

Remus Rusanu
fonte
10

Existem (agora) potencialmente duas maneiras de realizar a compactação personalizada:

  1. A partir do SQL Server 2016, existem funções internas para COMPRESS e DECOMPRESS . Essas funções usam o algoritmo GZip.

  2. Use SQLCLR para implementar qualquer algoritmo que você escolher (como @Remus mencionado em sua resposta). Esta opção está disponível em versões anteriores ao SQL Server 2016, desde o SQL Server 2005.

    O GZip é uma escolha fácil, pois está disponível no .NET e nas bibliotecas suportadas do .NET Framework (o código pode estar em um SAFEAssembly). Ou, se você deseja o GZip, mas não deseja lidar com a codificação / implantação, pode usar o Util_GZip e o Util_GUnzip funções que estão disponíveis na versão gratuita do SQL # biblioteca SQLCLR (que eu sou o autor).

    Se você decidir usar o GZip, seja você mesmo codificando ou usando o SQL #, lembre-se de que o algoritmo usado no .NET para fazer a compactação GZip mudou para melhor na versão 4.5 do Framework (consulte a seção "Comentários" no MSDN página para a classe GZipStream ). Isso significa:

    1. Se você estiver usando o SQL Server 2005, 2008 ou 2008 R2 - todos vinculados ao CLR v 2.0, que lida com as versões 2.0, 3.0 e 3.5 do Framework -, as alterações feitas no Framework versão 4.5 não terão efeito e, infelizmente, você estará preso ao O algoritmo original e ruim do .NET.
    2. Se você estiver usando o SQL Server 2012 ou mais recente (até agora 2014 e 2016) - todos vinculados ao CLR v 4.0, que lida com as versões 4.0, 4.5.x, 4.6 do Framework -, poderá usar o algoritmo melhor e mais novo. O único requisito é que você tenha atualizado o .NET Framework no servidor executando o SQL Server para a versão 4.5 ou mais recente.

    No entanto, você não precisa usar o GZip e é livre para implementar qualquer algoritmo como esse.

OBSERVAÇÃO: todos os métodos mencionados acima são mais "soluções alternativas", em vez de substituições reais, mesmo que sejam tecnicamente "formas alternativas de compactar dados do NVARCHAR (MAX)". A diferença é que, com a compactação de dados incorporada - rowe page- oferecida pelo SQL Server, a compactação é tratada nos bastidores e os dados ainda são utilizáveis, legíveis e indexáveis. Mas compactar qualquer dado em um VARBINARYmeio significa que você está economizando espaço, mas renunciando a algumas funcionalidades. É verdade que uma string de 20k não é indexável, mas ainda pode ser usada em umWHERE, ou com quaisquer funções de cadeia. Para fazer qualquer coisa com um valor compactado personalizado, você precisará descompactá-lo rapidamente. Ao compactar arquivos binários (PDFs, JPEGs, etc), isso não é um problema, mas essa pergunta era específica dos NVARCHARdados.

Solomon Rutzky
fonte