Quelles sont les meilleures pratiques actuelles concernant le dimensionnement varchar dans SQL Server?


12

J'essaie de comprendre la meilleure façon de décider de la taille des colonnes varchar, à la fois du point de vue du stockage et des performances.

Performance
D'après mes recherches, il sembleque varchar (max) ne doit être utilisé que si vous en avez vraiment besoin; c'est-à-dire, si la colonne doit contenir plus de 8000 caractères, une des raisons étant le manque d'indexation (bien que je sois un peu méfiant à propos de l'indexation sur les champs varchar en général. ) et la compression (plus un problème de stockage). En fait, en général, les gens semblent recommander d'utiliser uniquement ce dont vous avez besoin, lorsque vous faites varchar (n) .... le surdimensionnement est mauvais, car les requêtes doivent prendre en compte la taille maximale possible. Mais il a également été déclaré que le moteur utiliserait la moitié de la taille indiquée comme estimation de la taille réelle moyenne des données. Cela impliquerait que l'on devrait déterminer, à partir des données, quelle est la taille moyenne, la doubler et l'utiliser comme n. Pour les données avec une variabilité très faible mais non nulle, cela implique jusqu'à un surdimensionnement 2x sur la taille maximale, ce qui semble beaucoup, mais peut-être pas? Des informations seraient appréciées.

Stockage
Après avoir lu comment fonctionne le stockage en ligne ou hors ligne et en gardant à l'esprit que le stockage réel est limité aux données réelles, il me semble en fait que le choix de n a peu ou pas d'incidence sur le stockage (outre en s'assurant qu'il est assez grand pour tout contenir). Même l'utilisation de varchar (max) ne devrait pas avoir d'impact sur le stockage. Au lieu de cela, un objectif peut être de limiter la taille réelle de chaque ligne de données à ~ 8 000 octets si possible. Est-ce une lecture précise des choses?

Contexte
Certaines de nos données clients fluctuent un peu, nous élargissons donc généralement les colonnes juste un peu plus qu'elles ne doivent l'être, disons 15 à 20% plus grandes, pour ces colonnes. Je me demandais s'il y avait d'autres considérations spéciales; par exemple, quelqu'un avec qui je travaille m'a dit d'utiliser 2 ^ n - 1 tailles (je n'ai cependant trouvé aucune preuve que ce soit une chose ....)

Je parle de la création de table initiale. Un client nous dira qu'il va commencer à nous envoyer une nouvelle table, et envoyer des échantillons de données (ou tout simplement le premier ensemble de données de production), que nous examinons et créer un tableau de notre côté pour contenir les données. Nous voulons faire le tableau de notre côté pour gérer les importations futures ainsi que ce qui est dans l'échantillon. Mais, certaines lignes sont appelées à s'allonger, nous les remplissons donc.

La question est de savoir combien, et existe-t-il des directives techniques?


MongoDB utilise l'allocation de disque 2 ^ n pour un document. SQL Server n'utilise pas cette stratégie.
Michael Green

Réponses:


19

Quel que soit le type de données spécifique, vous devez pouvoir stocker toutes les demandes d'application à stocker. Vous ne pouvez pas spécifier quelque chose de plus petit que la taille maximale de ce qui sera réellement enregistré.

Vous n'avez pas non plus besoin, ni ne souhaitez, de spécifier une longueur de colonne supérieure à la taille réelle maximale qui sera stockée pour diverses raisons: allocation de mémoire de requête, remplissant potentiellement la taille de ligne maximale et ne laissant aucune place pour l'ajout de colonnes dans l'avenir, etc.

Vrai, la chaîne de longueur variable et les colonnes binaires n'ont pas l'implication de stockage que les types de données de longueur fixe (chaîne / binaire / numérique / date / etc) font (bien que certaines de ces implications puissent être annulées via la compression des données ou l'utilisation de la SPARSEdéfinition de colonne option). Cependant, comme vous l'avez souligné, même s'il n'y a pas d'implication directe de stockage, il y a toujours une implication de performance de surestimer la mémoire requise pour les requêtes.

Soyez raisonnable. N'utilisez que ce dont vous avez besoin. Des considérations peuvent être prises en compte s'il existe une forte probabilité que la longueur de la colonne doive augmenter dans un proche avenir, mais gardez à l'esprit qu'il est plus facile d'agrandir la taille d'une colonne que de la réduire. Oui, certains travaux seront impliqués, mais comme ce travail est simplement "potentiel", alors que les implications de surdimensionnement sont "réelles", il est souvent préférable de définir des colonnes en fonction de ce dont vous avez réellement besoin, pas de ce que vous avez peut-être un peu -sorta pense que vous pourriez avoir besoin à l'avenir. De nombreux changements dont il est question ne se produisent jamais, et souvent les changements nécessaires ne sont pas prévisibles. Allez avec ce que vous savez.

Au lieu de cela, un objectif peut être de limiter la taille réelle de chaque ligne de données à ~ 8 000 octets si possible.

Je ne sais pas exactement où vous voulez en venir. SQL Server vous limitera physiquement à un peu plus de 8 000 octets. Utilisation des types de LOB - VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XMLet le désapprouvées TEXT, NTEXTet IMAGEtypes - permettent d' aller au - delà de cette limite de taille de la page initiale, mais qui est seulement en raison de placer un pointeur (16 octets ou plus, en fonction du type, et en fonction du taille de la valeur stockée hors ligne lors de l'utilisation des MAXtypes). La limite physique réelle de la page de données n'a pas changé.

Votre objectif doit être d'utiliser le moins d'espace physique pour stocker ce que l'application / l'entreprise doit stocker sans casser ou tronquer de sorte que la valeur incomplète perd son sens ou cause des problèmes en aval. Si vous devez stocker un objet de 12 000 caractères, utilisez-le, VARCHAR(MAX)car c'est ce dont vous avez besoin . Si vous stockez un numéro de téléphone ou un code postal / zip, il serait imprudent d'utiliser VARCHAR(100)et irresponsable à utiliser VARCHAR(MAX).

certaines de nos données clients fluctuent un peu, donc nous faisons généralement des colonnes juste un peu plus larges que nécessaire, disons 15-20% plus grandes, pour ces colonnes. Je me demandais s'il y avait d'autres considérations spéciales;

Tous les systèmes n'ont-ils pas au moins des données qui fluctuent? Tout système qui enregistre le nom d'une personne serait admissible, non? Il y a un écart assez important dans la longueur des noms. Et puis vous avez quelqu'un comme Prince aller changer son nom en symbole et maintenant vous avez un problème entièrement différent qui n'est pas de longueur. C'est comme ça que les choses sont.

Mais, pour jouer l'avocat du diable un instant: comment la valeur "15-20% plus grande que ce qui est nécessaire" ne peut-elle pas être la valeur réellement nécessaire ? Supposons qu'il y ait une discussion sur l'ajout d'une nouvelle colonne, et que quelqu'un suggère 50 caractères, puis quelqu'un d'autre dit: "Eh bien, 20% de plus, c'est 60 alors faisons 60 parce que quelqu'un pourrait en avoir 60". S'il est vrai qu'un client peut en avoir 60, alors 60 est, et a toujours été, la valeur réelle nécessaire, et 50 était erroné tout le temps.

Bien sûr, cela aiderait s'il y avait une indication quant à la source des données car:

  1. si vous faites "URL" 1024 et que quelqu'un a besoin de 1060, alors il devait être 1060 (de même, si vous créez une URL VARCHARet que vous vous plaignez qu'elle gâche les caractères Unicode qui sont maintenant autorisés dans les noms de domaine, alors cela devait être le cas NVARCHAR), mais
  2. si quelqu'un veut ajouter 1000 caractères à un champ de commentaire 500 caractères limite, il reste seulement besoin d'être 500. Les gens peuvent être moins bavard dans les commentaires (un énorme défi pour moi ;-), mais ProductSKUmieux d' être assez grand pour tous des SKU du client.

Je parle de la création de table initiale. Un client nous dira qu'il va commencer à nous envoyer une nouvelle table, et envoyer des échantillons de données (ou tout simplement le premier jeu de données de production), que nous examinons et créer un tableau de notre côté pour contenir les données. Nous voulons faire le tableau de notre côté pour gérer les importations futures ainsi que ce qui est dans l'échantillon. Mais, certaines lignes sont appelées à s'allonger, nous les remplissons donc. La question est de savoir combien, et existe-t-il des directives techniques?

Vous faites beaucoup d'hypothèses ici. Bien sûr, certains champs pourraient devenir plus gros. Mais là encore, ils pourraient ne pas. Ou, certains pourraient devenir plus petits. Certains peuvent passer de non-Unicode à être Unicode (une fois qu'ils se rendent compte que le monde devient plus petit et on ne peut pas supposer que les noms de famille n'auront que des caractères ASCII / anglais américain de base). Ou, ils pourraient arrêter d'envoyer un champ. Ou ils peuvent ajouter un ou plusieurs champs à l'avenir. Toute combinaison de ceci et d'autres choses. Alors pourquoi se concentrer uniquement sur les VARCHARcolonnes? Et s'ils envoient actuellement une INTvaleur et dans un an ou deux, ils atteignent la valeur maximale et commencent à envoyer une valeur BIGINT? Et s'ils ont un champ "status" avec des valeurs de 0 à 5. Allez-vous supposerINTqui est "rembourré" car il permet la croissance, mais devrait probablement l'être TINYINT?

La seule chose que vous pouvez prédire en toute sécurité est qu'essayer de prédire comment les données de vos clients vont changer sera plus souvent erroné qu'il ne l'est. Et être correct est une question de chance / coïncidence (sinon la chance, alors allez jouer à la loterie;).

La ligne directrice est donc:

  1. Ne perdez pas de temps et d'énergie à essayer de répondre à une question sans réponse.
  2. Au lieu de cela, concentrez-vous sur l'obtention d'autant d'informations que possible sur les données réelles de votre client, et allez-y (c.-à-d. Prise de décision basée sur les données ;-).

Vous avez déjà des exemples de données, c'est parfait. Mais n'oubliez pas que vous disposez également des coordonnées de votre client: téléphone et / ou email. Contactez-les! Demandez-leur leurs spécifications de données (tout comme votre système, les données actuellement dans leur système peuvent avoir une longueur maximale de 35, mais leur système l'a définie comme VARCHAR(50), et leur système acceptera jusqu'à cette longueur, auquel cas vous devez utiliser 50). Et demandez-leur s'ils ont des plans à court terme pour changer et de ces types de données (type et / ou taille).


1
Je suis d'accord avec Solomon, @ Aristotle2600 - cependant, vous voudrez peut-être jeter un oeil à ma réponse sur une question concernant les différences entre un varchar(255)et un varchar(256)pour quelques considérations supplémentaires
Max Vernon

Merci, j'avais l'impression que ce serait quelque chose comme ça, et "n'utilisez que ce dont vous avez besoin" n'est qu'une bonne pratique de gestion des ressources tout autour. Mais, certaines de nos données clients fluctuent un peu, nous élargissons donc généralement les colonnes juste un peu plus qu'elles ne doivent l'être, disons 15 à 20% plus grandes, pour ces colonnes. Je me demandais s'il y avait d'autres considérations spéciales; par exemple, quelqu'un avec qui je travaille m'a dit d'utiliser 2 ^ n - 1 tailles (je n'ai cependant trouvé aucune preuve que ce soit une chose ....). Mais il semble qu'il n'y ait rien d'autre que de garder les choses aussi petites que possible.
aristotle2600

1
@ aristotle2600 Vous ne savez pas comment appliquer "2 ^ n - 1", mais je dois quand même me demander: est-il même théoriquement possible de faire quelque chose de plus grand que nécessaire ? Cette taille de 15 à 20% plus grande ne serait -elle pas la taille nécessaire pour ne pas se casser? ;-). Je suis sûr que cela aiderait si vous étiez plus explicite dans la source des données, car a) si vous faites "URL" 1024 et que quelqu'un a besoin de 1060, alors il devait être 1060, mais b) si quelqu'un veut ajouter 1000 un champ à caractères de commentaire limite char 500, il reste seulement besoin d'être 500. Les gens peuvent entrer moins dans les commentaires, mais produit SKU mieux être assez grand.
Solomon Rutzky

@ aristotle2600 Je viens d'ajouter certains de vos commentaires ici dans la question car ils fournissent un bon contexte. J'ai également ajouté des trucs à la fin de ma réponse :)
Solomon Rutzky

Merci beaucoup pour votre réponse! Oui, les noms et adresses flottent. En ce qui concerne le paradoxe toujours croissant de 20%, je vois ce que vous voulez dire, mais je parle de la création de table initiale. Un client nous dira qu'il va commencer à nous envoyer une nouvelle table, et envoyer des échantillons de données (ou tout simplement le premier jeu de données de production), que nous examinons et créer un tableau de notre côté pour contenir les données. Nous voulons faire le tableau de notre côté pour gérer les importations futures ainsi que ce qui est dans l'échantillon. Mais, certaines lignes sont appelées à s'allonger, nous les remplissons donc. La question est de savoir combien, et existe-t-il des directives techniques?
aristotle2600
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.