103 votes

Est-ce qu'il y a un avantage à utiliser varchar(500) au lieu de varchar(8000) ?

J'ai lu à ce sujet sur les forums MSDN et ici et je ne suis toujours pas clair. Je pense que c'est correct : Varchar(max) sera stocké en tant que type de données texte, ce qui comporte des inconvénients. Donc, disons que votre champ sera fiablement sous les 8000 caractères. Comme un champ BusinessName dans ma table de base de données. En réalité, un nom d'entreprise sera probablement toujours en dessous (sortant un numéro de mon chapeau) de 500 caractères. Il semble que de nombreux champs varchar que je rencontre tombent bien en dessous du compte de caractères 8k.

Donc, devrais-je faire de ce champ un varchar(500) au lieu de varchar(8000) ? D'après ce que je comprends de SQL, il n'y a pas de différence entre les deux. Donc, pour simplifier les choses, je voudrais définir tous mes champs varchar comme varchar(8000). Est-ce que cela comporte des inconvénients ?

Lié : Taille des colonnes varchar (Je n'ai pas senti que celui-ci répondait à ma question).

7 votes

Imaginez essayer de faire rentrer un nom d'entreprise de 500 caractères sur une carte de visite... :)

2 votes

@OMG Poneys : chaque fois que je vois votre nom d'utilisateur, je ris. Maintenant, que disiez-vous? (Je rigole)

4 votes

@jcollum : SpaceMan Spiff aura toujours mon vote. Ce n'est pas vrai - n'importe Calvin & Hobbes fera l'affaire, mais surtout ceux concernant la sculpture de neige. Ou le tyrannosaure pilotant un F-14. Mais je m'égare...

134voto

Martin Smith Points 174101

Un exemple où cela peut faire une différence est que cela peut empêcher une optimisation des performances qui évite d'ajouter des informations de versionnement de ligne aux tables avec des déclencheurs après.

Cela est couvert par Paul White ici

La taille réelle des données stockées est sans importance - c'est la taille potentielle qui importe.

De même, si vous utilisez des tables optimisées en mémoire depuis 2016, il est possible d'utiliser des colonnes LOB ou des combinaisons de largeurs de colonnes qui pourraient potentiellement dépasser la limite en ligne mais avec une pénalité.

Les colonnes (Max) sont toujours stockées hors ligne. Pour les autres colonnes, si la taille de ligne de données dans la définition de table peut dépasser 8,060 octets, SQL Server déplace la ou les colonnes de longueur variable les plus grandes hors ligne. Encore une fois, cela ne dépend pas de la quantité de données que vous stockez là-bas.

Cela peut avoir un grand effet négatif sur la consommation de mémoire et les performances

Un autre cas où la sur-déclaration des largeurs de colonnes peut faire une grande différence est si la table sera jamais traitée en utilisant SSIS. La mémoire allouée pour les colonnes de longueur variable (non BLOB) est fixée pour chaque ligne dans un arbre d'exécution et est conforme à la longueur maximale déclarée des colonnes, ce qui peut entraîner une utilisation inefficace des tampons mémoire (exemple). Bien que le développeur de package SSIS puisse déclarer une taille de colonne plus petite que la source, cette analyse est mieux réalisée à l'avance et appliquée là-bas.

Dans le moteur SQL Server lui-même, un cas similaire est que lors du calcul de l'allocation de mémoire pour les opérations de tri, SQL Server suppose que les colonnes varchar(x) consommeront en moyenne x/2 octets.

Si la plupart de vos colonnes varchar sont plus remplies que cela, cela peut conduire à ce que les opérations de tri débordent vers tempdb.

Dans votre cas, si vos colonnes varchar sont déclarées comme 8000 octets mais ont en réalité des contenus bien inférieurs, votre requête se verra allouer de la mémoire dont elle n'a pas besoin, ce qui est évidemment inefficace et peut entraîner des attentes pour les allocations mémoire.

Cela est abordé dans la Partie 2 du Webcast des Ateliers SQL 1 téléchargeable ici ou voir ci-dessous.

use tempdb;

CREATE TABLE T(
id INT IDENTITY(1,1) PRIMARY KEY,
number int,
name8000 VARCHAR(8000),
name500 VARCHAR(500))

INSERT INTO  T 
(number,name8000,name500)
SELECT number, name, name /*<--Same contents in both cols*/
FROM master..spt_values

SELECT id,name500
FROM T
ORDER BY number

Screenshot

SELECT id,name8000
FROM T
ORDER BY number

Screenshot

1 votes

Donc, si presque toutes mes valeurs sont de 3 ou 4 caractères, ne peuvent jamais dépasser 4 caractères, et je veux éviter que les "opérations de tri débordent vers tempdb", je déclarerai ma colonne VARCHAR(8) et utiliserai une contrainte CHECK pour appliquer que la largeur de la colonne ne peut pas dépasser 4 caractères. Que pensez-vous?

12 votes

@AlexKuznetsov - Pour cette situation, je les déclarerais comme char(4) car il y a de toute façon un surcoût de 2 octets par colonne de variable.

1 votes

Lien valide pour le post SQL Kiwi sql.kiwi/2012/08/…

26voto

BBlake Points 1799

D'un point de vue du traitement, cela ne fera pas de différence d'utiliser varchar(8000) par rapport à varchar(500). C'est plutôt une sorte de "bonne pratique" de définir une longueur maximale qu'un champ doit contenir et de faire de votre varchar cette longueur. C'est quelque chose qui peut être utilisé pour aider à la validation des données. Par exemple, faire en sorte qu'une abréviation d'état soit composée de 2 caractères ou qu'un code postal soit composé de 5 ou 9 caractères. C'était autrefois une distinction plus importante lorsque vos données interagissaient avec d'autres systèmes ou interfaces utilisateur où la longueur du champ était critique (par exemple, un ensemble de données de fichiers plats mainframe), mais de nos jours je pense que c'est plus une habitude qu'autre chose.

3 votes

Ce que vous dîtes a du sens... pour les choses qui ont naturellement une longueur maximale. Mais que faites-vous lorsque la longueur maximale n'est pas évidente? Par exemple, un nom de société.

2 votes

Pour quelque chose comme ça, si je ne prévois pas de moyens de prévoir quelle pourrait être potentiellement la taille, alors j'irai généralement avec un varchar(8000) ou varchar(max), en fonction du type de données

4 votes

Il semble que cela fait une différence en termes de performance, même en 2017 : dba.stackexchange.com/a/162117/1822

14voto

Oliver Points 1790

Il existe quelques inconvénients aux grandes colonnes qui sont un peu moins évidentes et pourraient vous surprendre un peu plus tard :

  • Toutes les colonnes que vous utilisez dans un INDEX - ne doivent pas dépasser 900 octets
  • Toutes les colonnes dans une clause ORDER BY ne doivent pas dépasser 8060 octets. C'est un peu difficile à comprendre puisque cela ne s'applique qu'à certaines colonnes. Voir SQL 2008 R2 Row size limit exceeded pour plus de détails)
  • Si la taille totale de la ligne dépasse 8060 octets, vous obtenez un "débordement de page" pour cette ligne. Cela peut affecter les performances (Une page est une unité d'allocation dans SQLServer et est fixée à 8000 octets + un peu de surcharge. Le dépasser ne sera pas grave, mais c'est perceptible et vous devriez essayer de l'éviter si vous le pouvez facilement)
  • De nombreuses autres structures de données internes, tampons et enfin vos propres variables et variables de table doivent toutes refléter ces tailles. Avec des tailles excessives, une allocation de mémoire excessive peut affecter les performances

En règle générale, essayez d'être conservateur avec la largeur de la colonne. Si cela devient un problème, vous pouvez facilement l'élargir pour répondre aux besoins. Si vous remarquez des problèmes de mémoire plus tard, réduire ultérieurement une colonne large peut devenir impossible sans perdre de données et vous ne saurez pas par où commencer.

Dans votre exemple des noms d'entreprises, réfléchissez à l'endroit où vous prévoyez de les afficher. Y a-t-il vraiment de la place pour 500 caractères ?? Si ce n'est pas le cas, il est peu utile de les stocker de cette manière. http://en.wikipedia.org/wiki/List_of_companies_of_the_United_States liste certains noms d'entreprises et le maximum est d'environ 50 caractères. Je mettrais donc 100 comme maximum pour la colonne. Peut-être plus proche de 80.

11voto

gbn Points 197263

En dehors des meilleures pratiques (réponse de BBlake)

  • Vous recevez des avertissements sur la taille maximale de ligne (8060) octets et la largeur de l'index (900 octets) avec le DDL
  • Le DML se bloquera si vous dépassez ces limites
  • Le PADDING ANSI ON est la valeur par défaut, donc vous pourriez finir par stocker beaucoup d'espaces vides

41 votes

Juste pour clarifier à propos de ANSI PADDING ON: lorsque vous utilisez les types nvarchar et varchar, cela signifie uniquement que les espaces de fin sont conservés lors de l'insertion - ce n'est pas que les valeurs sont remplies d'espaces à la taille de la colonne, comme c'est le cas avec char et nchar.

3voto

Otis Points 427

Idéalement, vous voudriez aller plus petit que ça, jusqu'à une longueur raisonnable (500 n'est pas une taille raisonnable) et vous assurer que la validation du client attrape lorsque les données vont être trop grandes et envoie une erreur utile.

Alors que le varchar n'est pas vraiment réservé d'espace dans la base de données pour l'espace inutilisé, je me souviens que des versions de SQL Server ont eu un problème avec les lignes de base de données plus larges que certains nombres d'octets (je ne me souviens pas du nombre exact) et en fait jeter les données qui ne rentrent pas. Un certain nombre de ces octets étaient réservés pour des choses internes à SQL Server.

0 votes

Vrai, cela avait l'habitude d'être une préoccupation beaucoup plus grande également. Mais de nos jours, l'espace est vraiment bon marché donc je ne pense pas que ce soit une grande préoccupation à prendre en compte, du moins de mon point de vue.

0 votes

"(500 n'est pas une taille raisonnable)" pour quoi ? Un nom ? Un paragraphe ? Un article de blog ? Tout est très relatif à moins qu'il n'y ait des limites évidentes, comme un code postal ou un numéro de sécurité sociale.

2 votes

@jcollum : Dans votre exemple, 500 ne semble pas être une taille raisonnable pour un nom de société.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X