web-dev-qa-db-fra.com

varchar (max) partout?

Existe-t-il un problème avec la création de toutes vos colonnes de chaînes Sql Server 2008 varchar (max)? Mes tailles de chaîne autorisées sont gérées par l'application. La base de données devrait simplement persister ce que je lui donne. Vais-je prendre un coup de performance en déclarant que toutes les colonnes de chaînes sont de type varchar (max) dans Sql Server 2008, quelle que soit la taille des données qui y sont réellement incluses?

77
BowserKingKoopa

En utilisant VARCHAR(MAX) vous dites essentiellement à SQL Server "stocker les valeurs dans ce champ comme vous le voyez le mieux", SQL Server choisira alors de stocker les valeurs sous la forme d'un VARCHAR normal ou d'un LOB (Grand objet). En général, si les valeurs stockées sont inférieures à 8 000 octets, SQL Server traitera les valeurs comme un type VARCHAR normal.

Si les valeurs stockées sont trop grandes, la colonne peut déborder de la page vers les pages LOB, exactement comme pour les autres types de LOB (text, ntext et image) - si cela se produit, des lectures de page supplémentaires sont nécessaires pour lire les données stockées dans les pages supplémentaires (c'est-à-dire qu'il y a pénalement des performances), cependant cela ne se produit que si les valeurs stockées sont trop grandes .

En fait, sous SQL Server 2008 ou version ultérieure, les données peuvent déborder sur des pages supplémentaires, même avec les types de données de longueur fixe (par exemple VARCHAR(3,000)), mais ces pages sont appelées pages de données de débordement de ligne et sont traitées légèrement différemment.

Version courte: du point de vue du stockage, il n'y a aucun inconvénient à utiliser VARCHAR(MAX) sur VARCHAR(N) pour certains N.

(Notez que cela s'applique également aux autres types de champs de longueur variable NVARCHAR et VARBINARY)

FYI - Vous vous ne pouvez pas créer d'index sur les colonnes VARCHAR(MAX)

46
Justin

Les index ne peuvent pas dépasser 900 octets de large pour un. Vous ne pouvez donc probablement jamais créer d'index. Si vos données sont inférieures à 900 octets, utilisez varchar (900).

C'est un inconvénient: parce que cela donne

  • très mauvaise performance de recherche
  • pas de contraintes uniques
32
gbn

Simon Sabin a écrit un article à ce sujet il y a quelque temps. Je n'ai pas le temps de le saisir maintenant, mais vous devriez le rechercher, car il arrive à la conclusion que vous ne devriez pas utiliser varchar (max) par défaut.

Modifié: Simon a quelques articles sur varchar (max). Les liens dans les commentaires ci-dessous le montrent très bien. Je pense que le plus important est http://sqlblogcasts.com/blogs/simons/archive/2009/07/11/String-concatenation-with-max-types-stops-plan-caching.aspx =, qui parle de l'effet de varchar (max) sur la mise en cache du plan. Le principe général est d'être prudent. Si vous n'avez pas besoin que ce soit max, alors n'utilisez pas max - si vous avez besoin de plus de 8000 caractères, alors bien sûr ... allez-y.

9
Rob Farley

Pour cette question en particulier quelques points que je ne vois pas mentionnés.

  1. Sur 2005/2008/2008 R2 si une colonne LOB est incluse dans un index, cela bloquera les reconstructions d'index en ligne.
  2. En 2012, la restriction de reconstruction d'index en ligne est levée mais les colonnes LOB ne peuvent pas participer à la nouvelle fonctionnalité Ajout de colonnes NOT NULL en tant qu'opération en ligne .
  3. Les verrous peuvent être supprimés plus longtemps sur les lignes contenant des colonnes de ce type de données. ( plus )

Quelques autres raisons sont couvertes dans ma réponse quant à pourquoi pas varchar(8000) partout .

  1. Vos requêtes peuvent finir par demander d'énormes allocations de mémoire non justifiées par la taille des données.
  2. Sur table avec des déclencheurs, il peut empêcher une optimisation sans ajout de balises de version.
5
Martin Smith

J'ai posé la question similaire plus tôt. a obtenu des réponses intéressantes. check it out ici Il y avait un site qui avait un gars qui parlait au détriment de l'utilisation de colonnes larges, mais si vos données sont limitées dans l'application, mes tests l'ont réfuté. Le fait que vous ne puissiez pas créer d'index sur les colonnes signifie que je ne les utiliserais pas tout le temps (personnellement, je ne les utiliserais pas beaucoup du tout, mais je suis un peu puriste à cet égard). Cependant, si vous savez qu'il n'y a pas grand-chose en eux, je ne pense pas qu'ils soient si mauvais. Si vous effectuez un tri sur les colonnes d'un jeu d'enregistrements avec un varchar (max) (ou toute colonne large étant char ou varchar), vous risquez de subir des pénalités de performances. ceux-ci pourraient être résolus (si nécessaire) par des index, mais vous ne pouvez pas placer les index sur varchar (max). Si vous voulez pérenniser vos colonnes, pourquoi ne pas simplement les mettre à quelque chose de raisonnable. par exemple, une colonne de nom contient 255 caractères au lieu de max ... ce genre de chose.

4
AtaLoss

Il y a une autre raison pour éviter d'utiliser varchar (max) sur toutes les colonnes. Pour la même raison que nous utilisons des contraintes de vérification (pour éviter de remplir des tableaux avec des ordures causées par des logiciels erronés ou des entrées utilisateur), nous voudrions nous prémunir contre tout processus défectueux qui ajouterait beaucoup plus de données que prévu. Par exemple, si quelqu'un ou quelque chose essayait d'ajouter 3000 octets dans un champ City, nous saurions avec certitude que quelque chose ne va pas et voudrions arrêter le processus de manière définitive pour le déboguer le plus tôt possible. Nous saurions également qu'un nom de ville de 3000 octets ne pourrait pas être valide et gâcherait les rapports et autres si nous essayions de l'utiliser.

1
Larry Ness

Idéalement, vous ne devez autoriser que ce dont vous avez besoin. Cela signifie que si vous êtes certain qu'une colonne particulière (disons une colonne de nom d'utilisateur) ne comptera jamais plus de 20 caractères, l'utilisation d'un VARCHAR (20) par rapport à un VARCHAR (MAX) permet à la base de données d'optimiser les requêtes et les structures de données.

Depuis MSDN: http://msdn.Microsoft.com/en-us/library/ms176089.aspx

Variable-length, non-Unicode character data. n can be a value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes.

Allez-vous vraiment vous rapprocher de 2 ^ 31-1 octets pour ces colonnes?

1
leepowers