118 votes

Importance de la longueur des varchars dans les tables MySQL

J'ai une table MySQL dans laquelle les lignes sont insérées dynamiquement. Comme je ne peux pas être certain de la longueur des chaînes de caractères et que je ne veux pas qu'elles soient coupées, je les transforme en varchar(200), ce qui est généralement beaucoup plus grand que ce dont j'ai besoin. Le fait de donner à un champ varchar une longueur bien supérieure à celle dont j'ai besoin a-t-il un impact important sur les performances ?

1 votes

Une table avec un seul index VARCHAR(255) utf8mb4 avec ~ 150k lignes mesurait 11.5MB. Une table avec une VARCHAR(48) utf8mb4 Une colonne indexée avec les mêmes données (longueur maximale de 46 caractères) utilise 4,5 Mo. Ce n'est pas vraiment une grande différence dans les requêtes, car la colonne est indexée. Mais cela s'ajoute aux E/S des requêtes et à des choses comme les sauvegardes de la base de données.

317voto

Bill Karwin Points 204877

Il y a un impact possible sur les performances : dans MySQL, les tables temporaires et les MEMORY les tables stockent un VARCHAR comme une colonne de longueur fixe, remplie à sa longueur maximale. Si vous concevez VARCHAR colonnes beaucoup plus grandes que la plus grande taille dont vous avez besoin, vous consommerez plus de mémoire que nécessaire. Cela affecte l'efficacité du cache, la vitesse de tri, etc.

33 votes

+1. J'ai également vu certains pilotes JDBC qui allouent suffisamment d'espace pour la taille maximale lors de la mise en place des tampons pour récupérer les lignes. Inutile de dire que cela provoque beaucoup d'angoisse et de grincements de dents quand un clown vient de faire varchar(50000) juste au cas où quelqu'un aurait un nom de famille très grand :-)

21 votes

+1. C'est un impact important et je crois que c'est la vraie réponse à cette question.

6 votes

Cette réponse et la réponse acceptée sont toutes deux nécessaires pour comprendre la réponse correcte au PO.

59voto

Alex Martelli Points 330805

Non, dans le sens où si les valeurs que vous stockez dans cette colonne sont toujours (disons) inférieures à 50 caractères, déclarer la colonne en tant que varchar(50) o varchar(200) a les mêmes performances.

12 votes

Pas exactement la vérité. Voir la réponse de Bill Karwin

8 votes

Je pense qu'une réponse comme celle-ci devrait être étayée par des documents, des repères ou quelque chose de similaire.

14voto

OMG Ponies Points 144785

VARCHAR est idéal pour la situation que vous décrivez, car il signifie "caractère variable" - la limite, basée sur votre exemple, serait de 200 caractères, mais tout ce qui est inférieur est accepté. et ne remplira pas la taille allouée de la colonne.

Les VARCHAR prennent également moins de place - les valeurs sont stockées sous la forme d'un préfixe d'un ou deux octets de longueur, plus les données. Le préfixe de longueur indique le nombre d'octets de la valeur. Une colonne utilise un octet de longueur si les valeurs ne nécessitent pas plus de 255 octets, deux octets de longueur si les valeurs peuvent nécessiter plus de 255 octets.

Pour plus d'informations sur la comparaison entre les types de données MySQL CHAR et VARCHAR, voir ce lien .

1 votes

Toute personne intéressée par le stockage MySQL (à propos de CHAR et VARCHAR) devrait lire le lien mentionné dans cette réponse. Merci !

14voto

Nudge Points 77

La taille est synonyme de performance ! Plus la taille est petite, mieux c'est. Pas aujourd'hui ni demain, mais un jour, vos tables atteindront une taille où il y aura de sérieux goulots d'étranglement, quelle que soit la conception que vous avez mise en place. Mais vous pouvez prévoir certains de ces goulets d'étranglement potentiels dans votre phase de conception qui sont susceptibles de se produire en premier et essayer d'étendre le temps votre db fonctionnera rapidement et heureusement jusqu'à ce que vous ayez besoin de repenser votre schéma ou de l'échelle horizontale en ajoutant plus de serveurs.

Dans votre cas, il y a de nombreuses fuites de performance que vous pouvez rencontrer : Les grandes jointures sont presque impossibles avec de longues varchar colonnes. L'indexation sur ces colonnes est une vraie plaie. Votre disque doit stocker les données. Une page de mémoire peut contenir moins de rangées et les balayages de table seront beaucoup plus lents. De plus, le cache des requêtes ne vous sera probablement d'aucune aide dans ce cas.

Vous devez vous demander : Combien d'insertions par an peuvent avoir lieu ? Quelle est la longueur moyenne ? Est-ce que j'ai vraiment besoin de plus de 200 caractères ou est-ce que je peux attraper cela dans le front-end de mon application, même en informant les utilisateurs de la longueur maximale ? Puis-je diviser la table en une table étroite pour l'indexation et le balayage rapides et une autre pour contenir des données supplémentaires, moins fréquemment utilisées et de taille croissante ? Puis-je classer les données varchar possibles dans des catégories et extraire ainsi certaines des données dans quelques colonnes plus petites, peut-être de type int ou bool, et réduire la colonne varchar de cette façon ?

Vous pouvez faire beaucoup de choses ici. Il est peut-être préférable de partir d'une première hypothèse, puis de revoir la conception étape par étape en utilisant des données de performance mesurées en situation réelle. Bonne chance.

0 votes

+1 pour répertorier les options de conception et explorer l'impact. Très utile pour ma question également. stackoverflow.com/q/12083089/181638

5 votes

La définition d'une longueur maximale élevée a-t-elle un impact réel sur les performances, ou celles-ci sont-elles uniquement déterminées par la taille réelle ?

5voto

DCH Points 11

Certains d'entre vous se trompent en pensant qu'un varchar(200) occupe plus de place sur le disque qu'une varchar(20) . Ce n'est pas le cas. Ce n'est que lorsque vous dépassez 255 caractères que mysql utilise un octet supplémentaire pour déterminer la longueur de l'adresse IP. varchar données de terrain.

9 votes

Ce n'est pas le cas pour les tables temporaires et les MEMORY tables.

5 votes

Chaque fois que votre requête select utilise une table temporaire (opérations group et order by, entre autres), elle convertit varchar(200) en char(200) et les performances s'en ressentent.

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