web-dev-qa-db-fra.com

Importance de la longueur de varchar dans la table MySQL

J'ai une table MySQL où les lignes sont insérées dynamiquement. Parce que je ne peux pas être certain de la longueur des chaînes et que je ne veux pas les couper, je leur donne varchar (200) qui est généralement beaucoup plus gros que ce dont j'ai besoin. Existe-t-il un gros problème de performance en donnant à un champ varchar beaucoup plus de longueur que nécessaire?

101
Brian

Non, en ce sens que si les valeurs que vous stockez dans cette colonne ont toujours (par exemple) moins de 50 caractères, la déclaration de la colonne en tant que varchar(50) ou varchar(200) a la même performance.

58
Alex Martelli

Un impact sur les performances est possible: dans MySQL, les tables temporaires et les tables MEMORY stockent une colonne VARCHAR sous forme de colonne de longueur fixe, complétée à sa longueur maximale. Si vous concevez des colonnes VARCHAR beaucoup plus grandes que la taille maximale dont vous avez besoin, vous utiliserez plus de mémoire que nécessaire. Cela affecte l'efficacité du cache, la vitesse de tri, etc.

265
Bill Karwin

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 rien de moins n'est accepté et ne remplira pas la taille de la colonne . 

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

Pour plus d'informations sur la comparaison des types de données MySQL CHAR avec VARCHAR, voir this link .

13
OMG Ponies

La taille est la performance! Plus la taille est petite, mieux c'est. Pas aujourd'hui ni demain, mais un jour ou l'autre, vos tables atteindront une taille telle que de sérieux goulots d'étranglement, peu importe le design que vous avez disposé. Cependant, vous pouvez prévoir certains des goulots d'étranglement potentiels de votre phase de conception qui risquent de se produire en premier et essayer de prolonger le temps d'exécution de votre base de données jusqu'à ce que vous deviez repenser votre schéma ou votre échelle horizontalement en ajoutant davantage de serveurs.

Dans votre cas, vous pouvez rencontrer de nombreuses pertes de performances: Les jointures volumineuses sont presque impossibles avec de longues colonnes varchar. L'indexation sur ces colonnes est un vrai tueur. Votre disque doit stocker les données. Une page mémoire peut contenir moins de lignes et les analyses de table seront beaucoup plus lentes. De plus, il est peu probable que le cache de requêtes vous aide ici.

Vous devez vous demander: combien d'inserts par an peuvent se produire? Quelle est la longueur moyenne? Ai-je vraiment besoin de plus de 200 caractères ou puis-je le saisir dans mon application frontale, même en informant les utilisateurs de la longueur maximale? Puis-je scinder la table en une table étroite pour une indexation et une analyse rapides et une autre pour la conservation de données supplémentaires dont la taille est en augmentation, dont la nécessité est moins fréquente? Puis-je taper les données varchar possibles en catégories et extraire ainsi certaines des données dans quelques colonnes plus petites, peut-être de type int ou bool, et rétrécir la colonne varchar de cette façon?

Vous pouvez faire beaucoup de choses ici. Il peut être préférable de commencer par une première hypothèse, puis de revoir la conception étape par étape en utilisant des données de performances mesurées réelles. Bonne chance.

13
Nudge

Performance? Non. Stockage sur disque? Oui, mais c'est pas cher et copieux. À moins que votre base de données atteigne une échelle en téraoctets, vous êtes probablement d'accord.

4
duffymo

Certains d’entre vous pensent à tort qu’une varchar(200) occupe plus d’une table sur le disque qu’une varchar(20). Ce n'est pas le cas. Mysql utilise un octet supplémentaire pour déterminer la longueur des données du champ varchar uniquement lorsque vous dépassez 255 caractères.

4
DCH

Il peut y avoir des pertes de performances - mais généralement pas à un niveau que la plupart des utilisateurs remarqueraient.

Lorsque la taille de chaque champ est connue à l'avance, MySQL sait exactement combien d'octets il y a entre chaque champ/ligne et peut faire défiler la page sans lire toutes les données. L'utilisation de caractères variables réduit cette capacité d'optimisation.

varchar entraîne-t-il un impact négatif sur les performances en raison de la fragmentation des données?

Encore mieux, char vs varchar .

Dans la plupart des cas, cela vous convient, mais il y a une différence , et pour les bases de données à grande échelle, il y a des raisons pour lesquelles vous choisiriez un ou l'autre.

1
Rizwan Kassim

Vous devriez essayer de voir une colonne varchar de la même manière que vous le feriez avec une colonne char dans la plupart des scénarios et de définir la longueur de manière conservatrice. Vous n'avez pas toujours besoin de penser au modificateur var en tant que facteur influant sur votre prise de décision concernant la longueur maximale. Cela devrait être considéré comme un indice de performance au lieu que les chaînes fournies soient de longueurs variables.

Ce n'est pas une directive qui doit être strictement suivie par les internes de la base de données, elle peut être complètement ignorée. Faites attention cependant, car parfois une implémentation peut fuir (longueur fixe et rembourrage par exemple) même si cela ne devrait pas être le cas dans un monde idéal.

Si vous avez un varchar (255), vous n’aurez aucune garantie que ses performances se comporteront toujours différemment d’un caractère (255) en toutes circonstances.

Il peut sembler facile de choisir une valeur telle que 255, 65535, etc., en ligne avec les conseils donnés dans le manuel concernant les exigences de stockage. Cela donne l’impression que toute valeur entre 0 (oui, c’est une chose) et 255 aura le même impact. Cependant, ce n'est pas quelque chose qui peut être pleinement garanti.

Les besoins de stockage tendent à être vrais ou un bon indicateur de moteurs de stockage persistants décents et matures en termes de stockage en ligne. Ce n'est pas un indicateur aussi puissant pour des éléments tels que les index.

C'est parfois une question difficile: combien de temps une ficelle doit-elle être longue pour la placer au plus haut, vous savez qu'elle devrait être à l'intérieur, mais cela n'a aucun impact. Malheureusement, il s’agit souvent d’une tâche laissée à l’utilisateur, ce qui est quelque peu arbitraire. Vous ne pouvez pas vraiment dire de ne jamais surdimensionner une chaîne car il peut arriver que vous ne soyez pas tout à fait sûr.

Vous devez vous assurer que les requêtes MySQL génèrent une erreur lorsqu'une chaîne est trop longue plutôt que tronquée, afin qu'au moins vous sachiez si elle pourrait être trop courte en termes d'émission d'erreur. Redimensionner des colonnes pour les agrandir ou les réduire peut être une opération DDL coûteuse, gardez cela à l’esprit.

Le jeu de caractères doit également être pris en compte lorsque la longueur et la performance entrent en jeu. La longueur fait référence à cela plutôt que d'octets. Si vous utilisez par exemple utf8 (pas MB4), alors varchar (255) est vraiment varbinary (3 * 255). Il est difficile de savoir comment cela se passera sans qu'il soit nécessaire de lancer des tests et d'examiner le code source/la documentation de manière approfondie. De ce fait, une longueur excessive peut avoir un impact gonflé de manière inattendue. cela ne s'applique pas seulement à la performance. Si vous devez un jour modifier le jeu de caractères d’une colonne varchar en un jeu plus grand, vous risquez de vous heurter à une limite sans recours si vous autorisez la présence de chaînes longues gratuites qui auraient pu être évitées. Il s’agit normalement d’un problème assez complexe, mais il a été soulevé récemment. C’était récemment l’introduction de utf8mb4 pour MySQL et des index qui limitaient la longueur des clés.

S'il s'avère que MAX (LENGTH (column)) est toujours <64 (par exemple, s'il était décidé qu'il y aurait une limite sur les entrées qui ne correspondait pas à la définition de la colonne) mais que vous avez varchar (255), il y a Il y a de fortes chances que vous utilisiez quatre fois plus d'espace que nécessaire dans certains scénarios.

Cela pourrait inclure:

  • Différents moteurs, certains peuvent l'ignorer complètement.
  • La taille de la mémoire tampon, par exemple update ou insert, peut devoir allouer la totalité des 255 (bien que je n’aie pas vérifié le code source pour le prouver, ce n’est qu’une hypothèse).
  • Les index, ce sera immédiatement évident si vous essayez de créer une clé composite à partir d’un grand nombre de colonnes varchar (255).
  • Tables intermédiaires et éventuellement ensembles de résultats. Étant donné le fonctionnement des transactions, il est parfois impossible d'utiliser la longueur maximale réelle des chaînes d'une colonne, par opposition à la limite définie.
  • Les optimisations prédictives internes peuvent prendre la longueur maximale en entrée.
  • Changements dans les versions d'implémentation de la base de données.

En règle générale, il n'est vraiment pas nécessaire qu'un varchar soit plus long que ce soit, problèmes de performances ou non, je vous recommande donc de vous y tenir dès que vous le pourrez. Faire plus d'efforts pour échantillonner la taille de vos données, imposer une limite réelle ou découvrir la limite réelle en demandant/recherche est l'approche idéale.Lorsque vous ne le pouvez pas, si vous souhaitez utiliser varchar (255) pour les cas douteux, je vous recommande de faire la science. Cela peut consister à dupliquer la table, à réduire la taille de la colonne var char, à y copier les données de l'original et à examiner la taille des données index/row (indexez également la colonne, essayez-la également en tant que clé primaire). peut se comporter différemment dans InnoDB car les lignes sont classées par clé primaire). De cette façon, vous saurez au moins si vous avez un impact sur IO, ce qui est généralement l'un des goulots d'étranglement les plus sensibles. Il est plus difficile de tester l'utilisation de la mémoire, il est difficile de le tester de manière exhaustive. Je recommanderais de tester les pires situations potentielles (requêtes avec beaucoup de résultats intermédiaires en mémoire, vérifiez avec explique pour les tables temporaires volumineuses, etc.).

Si vous savez qu'il n'y aura pas beaucoup de lignes dans la table, si vous n'utilisez pas la colonne pour les jointures, les index (en particulier composites, uniques), etc., vous n'aurez probablement pas beaucoup de problèmes.

If you know there's not going to be many rows in the table, you aren't going to use the column for joins, indexes (especially composite, unique), etc then you most likely wont have many problems.

0
jgmjgm

En tant que varchar, plutôt que simplement char, la taille est basée sur un champ interne pour indiquer sa longueur réelle et la chaîne elle-même. L'utilisation de varchar (200) n'est donc pas très différente de l'utilisation de varchar (150), si ce n'est que vous avez le potentiel pour stocker More. 

Et vous devriez considérer ce qui se passe sur une mise à jour, quand une ligne grandit. Mais si cela est rare, alors ça devrait aller. 

0
Rob Farley

Un autre point qui peut être mentionné est qu’il est préférable d’utiliser des lignes de longueur fixe plutôt que de varier. Par exemple, il vaut mieux avoir des colonnes comme char(n), bigint, date et ainsi de suite plutôt que varchar. Les meilleures performances du moteur de stockage MyISAM de MySQL sont obtenues lorsque la taille de la ligne est fixée.

0
Andronicus

comme le nom du type de données le suggère, il s’agit de VARCHAR, c’est-à-dire le stockage de données à caractères variables, le moteur mysql lui-même alloue la mémoire utilisée selon les données stockées, de sorte qu’il n’y ait aucune perte de performances.

0
user2903114