Modo alternativo per comprimere NVARCHAR (MAX)?


14

Sto cercando di comprimere alcune tabelle che hanno NVARCHAR(MAX)campi. Purtroppo, il rowe la pagecompressione non hanno l'impatto desiderio (solo ~ 100/200 MB salvato per 20 tavolo GB). Inoltre, non sono in grado di applicare le compressioni di archivio archivio di colonne e archivio di colonne perché non supportano la compressione dei NVARCHAR(MAX)campi.

Qualcuno può dire se ho qualche alternativa qui?

Suppongo anche che la compressione rowe pagenon abbiano effetto perché il contenuto delle NVARCHAR(MAX)colonne è unico.


2
I valori delle colonne sono sicuramente più grandi di 8000 caratteri? ad es. SELEZIONA MAX (CAST (LEN (widecolumn) AS BIGINT)) DA dbo.largeTable Altrimenti potresti convertirli in varchar ordinario e applicare un archivio di colonne in cluster.
wBob,

@wBob Anche se il valore più grande fosse solo di 2000 caratteri, la conversione non VARCHARcauserebbe potenzialmente la perdita di dati se si utilizzassero caratteri da più di 1 pagina di codice? Penso che il consiglio dovrebbe essere quello di convertire NVARCHAR(4000)se la lunghezza massima non è maggiore di 4000 perché tutti i valori sarebbero idonei per la compressione Unicode completa. Tuttavia, dalle informazioni nella domanda è probabilmente ipotizzabile che i valori superino i 4000 caratteri, motivo per cui al momento non vengono compressi.
Solomon Rutzky,

Risposte:


16

La compressione di pagine e righe non comprime i BLOB .

A causa delle loro dimensioni, i tipi di dati di grande valore vengono talvolta archiviati separatamente dai normali dati di riga nelle pagine per scopi speciali. La compressione dei dati non è disponibile per i dati archiviati separatamente.

Se si desidera comprimere i BLOB, è necessario memorizzarli come VARBINARY(MAX)e applicare l'algoritmo di compressione del flusso prescelto. Per esempio GZipStream. Ci sono molti esempi su come farlo, basta cercare GZipStream e SQLCLR.


10

Esistono (ora) potenzialmente due modi per ottenere una compressione personalizzata:

  1. A partire da SQL Server 2016 ci sono funzioni integrate per COMPRESS e DECOMPRESS . Queste funzioni utilizzano l'algoritmo GZip.

  2. Usa SQLCLR per implementare qualsiasi algoritmo che scegli (come menzionato da @Remus nella sua risposta). Questa opzione è disponibile nelle versioni precedenti a SQL Server 2016, a partire da SQL Server 2005.

    GZip è una scelta facile perché è disponibile in .NET e nelle librerie .NET Framework supportate (il codice può essere in un SAFEassembly). Oppure, se vuoi GZip ma non vuoi occuparti della codifica / distribuzione, puoi usare le funzioni Util_GZip e Util_GUnzip che sono disponibili nella versione gratuita della libreria SQL # SQLCLR (di cui sono l'autore).

    Se decidi di utilizzare GZip, che tu lo codifichi da solo o usi SQL #, tieni presente che l'algoritmo utilizzato in .NET per eseguire la compressione GZip è cambiato in Framework versione 4.5 per il meglio (vedi la sezione "Note" su MSDN pagina per la classe GZipStream ). Questo significa:

    1. Se si utilizza SQL Server 2005, 2008 o 2008 R2 - tutti collegati a CLR v 2.0 che gestisce le versioni Framework 2.0, 3.0 e 3.5 - la modifica apportata in Framework versione 4.5 non ha alcun effetto e purtroppo si è bloccati con Algoritmo sucky originale di .NET.
    2. Se si utilizza SQL Server 2012 o versioni successive (finora 2014 e 2016), tutte collegate a CLR v 4.0 che gestisce le versioni di Framework 4.0, 4.5.x, 4.6, è possibile utilizzare l'algoritmo più recente e migliore. L'unico requisito è che .NET Framework sul server che esegue SQL Server sia stato aggiornato alla versione 4.5 o successiva.

    Tuttavia, non devi usare GZip e sei libero di implementare qualsiasi algoritmo simile.

ATTENZIONE: tutti i metodi sopra indicati sono più "soluzioni alternative" anziché essere sostituzioni effettive, anche se tecnicamente sono "modi alternativi di comprimere i dati NVARCHAR (MAX)". La differenza è che con la compressione dei dati integrata - e - offerta da SQL Server, la compressione viene gestita dietro le quinte e i dati sono ancora utilizzabili, leggibili e indicizzabili. Ma comprimere tutti i dati in un modo che stai risparmiando spazio, ma rinunciare ad alcune funzionalità. È vero, una stringa 20k non è comunque indicizzabile, ma può ancora essere utilizzata in a clausola o con qualsiasi funzione stringa. Per fare qualsiasi cosa con un valore compresso personalizzato, è necessario decomprimerlo al volo. Quando si comprimono file binari (PDF, JPEG, ecc.) Questo non è un problema, ma questa domanda era specifica per i dati.rowpageVARBINARYWHERENVARCHAR

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.