Autre moyen de compresser NVARCHAR (MAX)?

14

J'essaie de compresser certaines tables qui ont des NVARCHAR(MAX)champs. Malheureusement, la rowet la pagecompression n'ont pas l'impact souhaité (seulement ~ 100/200 Mo économisés pour une table de 20 Go). En outre, je ne suis pas en mesure d'appliquer des compressions d'archivage de magasin de colonnes et de magasins de colonnes car elles ne prennent pas en charge la compression des NVARCHAR(MAX)champs.

Quelqu'un peut-il dire si j'ai des alternatives ici?

Je suppose également que la compression rowet pagen'ont pas d'effet car le contenu des NVARCHAR(MAX)colonnes est unique.

gotqn
la source
2
Les valeurs des colonnes sont-elles nettement supérieures à 8 000 caractères? par exemple SELECT MAX (CAST (LEN (widecolumn) AS BIGINT)) FROM dbo.largeTable Sinon, vous pourriez les convertir en varchar ordinaire et appliquer un magasin de colonnes en cluster.
wBob
@wBob Même si la valeur la plus élevée n'était que de 2000 caractères, la conversion ne provoquerait-elle pas VARCHARpotentiellement une perte de données si des caractères provenant de plus d'une page de codes sont utilisés? Je pense que le conseil devrait être de convertir en NVARCHAR(4000)si la longueur maximale n'est pas supérieure à 4000, car toutes les valeurs seraient éligibles pour la compression Unicode complète. Pourtant, il est probablement sûr de supposer à partir des informations de la question que les valeurs sont bien supérieures à 4000 caractères, c'est pourquoi elles ne sont pas en cours de compression.
Solomon Rutzky

Réponses:

16

La compression des pages et des lignes ne compresse pas les BLOBs .

En raison de leur taille, les types de données de grande valeur sont parfois stockés séparément des données de ligne normales sur des pages spéciales. La compression des données n'est pas disponible pour les données stockées séparément.

Si vous souhaitez compresser des BLOB, vous devez les stocker sous VARBINARY(MAX)et appliquer l'algorithme de compression de flux de votre choix. Par exemple GZipStream. Il existe de nombreux exemples pour ce faire, recherchez simplement GZipStream et SQLCLR.

Remus Rusanu
la source
10

Il existe (maintenant) potentiellement deux façons d'effectuer une compression personnalisée:

  1. À partir de SQL Server 2016, il existe des fonctions intégrées pour COMPRESS et DECOMPRESS . Ces fonctions utilisent l'algorithme GZip.

  2. Utilisez SQLCLR pour implémenter n'importe quel algorithme que vous choisissez (comme @Remus l'a mentionné dans sa réponse). Cette option est disponible dans les versions antérieures à SQL Server 2016, remontant jusqu'à SQL Server 2005.

    GZip est un choix facile car il est disponible dans .NET et dans les bibliothèques .NET Framework prises en charge (le code peut être dans un SAFEassembly). Ou, si vous voulez GZip mais ne voulez pas le coder / le déployer, vous pouvez utiliser les fonctions Util_GZip et Util_GUnzip qui sont disponibles dans la version gratuite de la bibliothèque SQL # SQLCLR (dont je suis l'auteur).

    Si vous décidez d'utiliser GZip, que vous le codiez vous-même ou que vous utilisiez SQL #, sachez que l'algorithme utilisé dans .NET pour effectuer la compression GZip a été amélioré dans Framework version 4.5 (voir la section "Remarques" sur le MSDN page pour la classe GZipStream ). Ça signifie:

    1. Si vous utilisez SQL Server 2005, 2008 ou 2008 R2 - tous liés à CLR v 2.0 qui gère les versions Framework 2.0, 3.0 et 3.5 - la modification apportée dans Framework version 4.5 n'a aucun effet et vous êtes malheureusement coincé avec Algorithme original et succulent de .NET.
    2. Si vous utilisez SQL Server 2012 ou plus récent (jusqu'à présent 2014 et 2016) - tous liés à CLR v 4.0 qui gère les versions Framework 4.0, 4.5.x, 4.6 - alors vous pouvez utiliser le plus récent et meilleur algorithme. La seule condition requise est que vous ayez mis à jour le .NET Framework sur le serveur exécutant SQL Server pour être la version 4.5 ou plus récente.

    Cependant, vous n'avez pas besoin d'utiliser GZip et êtes libre d'implémenter n'importe quel algorithme comme.

VEUILLEZ NOTER: toutes les méthodes mentionnées ci-dessus sont davantage des «solutions de contournement» au lieu d'être de véritables remplacements, même s'il s'agit techniquement de «moyens alternatifs de compresser les données NVARCHAR (MAX)». La différence est qu'avec la compression de données intégrée - rowet page- offerte par SQL Server, la compression est gérée en arrière-plan et les données sont toujours utilisables, lisibles et indexables. Mais en compressant toutes les données, VARBINARYvous économisez de l'espace, mais vous abandonnez certaines fonctionnalités. Certes, une chaîne de 20k n'est pas indexable de toute façon, mais elle peut toujours être utilisée dans unWHEREou avec n'importe quelle fonction de chaîne. Pour faire quoi que ce soit avec une valeur compressée personnalisée, vous devez la décompresser à la volée. Lors de la compression de fichiers binaires (PDF, JPEG, etc.), ce n'est pas un problème, mais cette question était spécifique aux NVARCHARdonnées.

Solomon Rutzky
la source