Quelles sont les principales différences de performances entre varchar et nvarchar types de données SQL Server?
Je suis en train de travailler sur une base de données pour une petite application web à mon école, à l'aide de SQL Server 2005
.
Je vois un couple d'écoles de pensée sur la question de la varchar
vs nvarchar
:
- Utilisation
varchar
, sauf si vous avez affaire à un beaucoup de l'internationalisation de données, puis utilisernvarchar
. - Suffit d'utiliser
nvarchar
pour tout.
Je commence à en voir le fond de la vue 2. Je sais que nvarchar prend deux fois plus d'espace, mais qui n'est pas nécessairement une affaire énorme puisque c'est seulement pour stocker des données pour quelques centaines d'étudiants. Pour moi, il me semble qu'il serait plus facile de ne pas s'en soucier et juste permettre à tout pour utiliser le type de données nvarchar. Ou est-il quelque chose que je suis absent?
- question similaire ici: stackoverflow.com/questions/312170/... EDIT par le dorfier: ce qui est intéressant est venu à la conclusion opposée.
- référence beaucoup plus vaste thread qui est venu à la conclusion opposée. stackoverflow.com/questions/312170/...
- Jason: j'espère que ce n'est pas inadapté à la demande, mais pouvez-vous s'il vous plaît envisager de changer la accepté de répondre à gbn de l'. JoeBarone la réponse est horriblement mal pour de nombreuses raisons. Avoir "accepté" induit en erreur les novices en faisant de mauvais choix. Il est inutile et un gaspillage à "toujours utiliser
NVARCHAR
", et cela peut avoir des impacts très négatifs sur les performances et les coûts de matériel / les budgets. Quelques lignes, voire quelques milliers, n'a pas d'importance. Mais les systèmes de croître plus rapidement que les gens attendent, de sorte que le courant a accepté de répondre est un mauvais service à la communauté. Je vous remercie.
Vous devez vous connecter pour publier un commentaire.
Toujours utiliser le type de données nvarchar.
Vous pouvez ne jamais avoir besoin les caractères à double octet pour la plupart des applications. Toutefois, si vous avez besoin de soutien à double octet langues et vous n'avez qu'un seul octet de soutien dans votre schéma de base de données, il est vraiment cher pour revenir en arrière et modifier tout au long de votre application.
Le coût de la migration d'une application de type varchar nvarchar sera beaucoup plus que le peu d'espace disque supplémentaire que vous allez utiliser dans la plupart des applications.
NVARCHAR
? Vous n'avez pas de travail pour EMC, Oracle, pensez-vous? 😉De l'espace disque n'est pas la question... mais la mémoire et les performances.
Le Double de la page lit, double la taille de l'index, étrange COMME et = constante de comportement etc
Avez-vous besoin pour stocker les Chinois etc script? Oui ou non...
Et à partir de MS BOL "De stockage et les Effets sur les Performances de l'Unicode"
Modifier:
Récente DONC, la question en soulignant comment le mauvais type nvarchar la performance peut être...
SQL Server utilise élevé CPU lors de la recherche à l'intérieur de chaînes de type nvarchar
strange LIKE and = constant behaviour
partie. Pourriez-vous ajouter quelques détails de ce que vous entendez par là?Être cohérent! REJOIGNEZ-ing un VARCHAR de type NVARCHAR a un gros gain de performance.
nvarchar
àvarchar
vs conversionnvarchar
àvarchar
et de se joindre àvarchar
. À moins bien sûr que vous voulait être cohérent dans la colonne type de données, pas l'adhésion.VARCHAR
etNVARCHAR
, qui doit être dû à l'indexation de laVARCHAR
colonne avec le type de Classement utilisé pour la colonne (et donc de l'indice). Je couvre ce sujet en détail dans le blog suivant: Impact sur des Indices Lors du Mixage de type VARCHAR et NVARCHAR Types.nvarchar va avoir une surcharge importante de mémoire, de stockage et d'indexation, de sorte que si les spécifications dicter qu'il aura vraiment jamais être nécessaire, n'est pas la peine.
Je n'aurais pas un dur et rapide "toujours nvarchar" règle car il peut être un gaspillage dans de nombreuses situations - notamment ETL de ASCII/EBCDIC ou les identifiants et code colonnes qui sont souvent les clés et les clés étrangères.
D'autre part, il y a beaucoup de cas de colonnes, où je voudrais être sûr de poser cette question au début et si je n'ai pas de réponse absolue immédiatement, je ferais la colonne de type nvarchar.
Je hésitez pas à en ajouter encore une autre réponse ici comme il y a déjà quelques, mais quelques points doivent être faites, qui n'ont pas été fait ou pas fait clairement.
Première: Ne pas toujours utiliser
NVARCHAR
. C'est très dangereux, et souvent coûteuses, de l'attitude ou de l'approche. Et c'est pas mieux de dire "Jamais utilisez les curseurs", car ils sont parfois le moyen le plus efficace de résoudre un problème particulier, et le travail commun autour de faire unWHILE
boucle sera presque toujours plus lent qu'un correctement fait du Curseur.Le seul moment où vous devez utiliser le terme "toujours", c'est quand vous conseillant de "faire toujours ce qui est mieux pour la situation". Accordé qui est souvent difficile à déterminer, surtout lorsqu'on tente d'équilibrer les gains à court terme en temps de développement (manager: "nous avons besoin de cette fonctionnalité, que vous ne connaissiez pas jusqu'à maintenant -- il y a une semaine!") avec à long terme des coûts de maintenance (gestionnaire qui, au départ, des pressions équipe de 3 mois dans 3 semaines sprint: "pourquoi sommes-nous à avoir ces problèmes de performances? Comment pourrions-nous l'avez peut-être fait X qui n'a pas de flexibilité? Nous ne pouvons nous permettre un sprint ou deux pour résoudre ce problème. Que pouvons-nous faire dans une semaine si nous pouvons revenir à nos articles de priorité? Et nous avons certainement besoin de passer plus de temps dans la conception si cela ne veut pas continuer comme ça!").
Deuxième: @gbn la réponse de touche sur certains points très importants à considérer lors de la prise de certaines données de la modélisation des décisions lorsque le chemin n'est pas 100% clair. Mais il n'y a même plus à prendre en compte:
Perdre de l'espace a un énorme des conséquences en cascade sur l'ensemble du système. J'ai écrit un article qui va en explicite en détail sur ce sujet: Le Disque N'Est Pas Cher! ORLY? (inscription gratuite obligatoire; désolé je n'ai pas de contrôle que de la politique).
Troisième: Alors que certaines réponses sont mal en se concentrant sur le "c'est une petite application" aspect, et certains sont correctement ce qui suggère "l'utilisation de ce qui est approprié", aucune des réponses ont fourni un véritable orientation de l'O. P. Un détail important mentionné dans la Question, c'est que c'est une page web de leur école. Super! Nous pouvons donc suggérer que:
NVARCHAR
depuis, au fil du temps, il est seulement plus susceptibles que les noms d'autres cultures, seront à l'affiche jusqu'en ces lieux.VARCHAR
avec le Code approprié de la Page (qui est déterminé par le Classement du domaine).INT
/TINYINT
depuis des codes ISO sont de longueur fixe, lisible par l'homme, et bien, norme 🙂 utilisezCHAR(2)
pour les deux codes de lettres etCHAR(3)
si à l'aide de code à 3 lettres. Et pensez à utiliser un Classement binaire commeLatin1_General_100_BIN2
.VARCHAR
car c'est une norme internationale à ne jamais utiliser la lettre en dehors de A-Z. Et oui, toujours utiliserVARCHAR
même si le stockage de NOUS codes postaux et pas INT depuis les codes postaux ne sont pas des numéros, ils sont des chaînes de caractères, et certains d'entre eux ont un "0". Et pensez à utiliser un Classement binaire commeLatin1_General_100_BIN2
.NVARCHAR
depuis ces deux peut maintenant contenir des caractères Unicode.Quatrième: Maintenant que vous avez
NVARCHAR
prise de données jusqu'à deux fois plus d'espace que nécessaire pour les données qui s'intègre parfaitement dansVARCHAR
("va très bien" = ne pas se transformer en "?") et en quelque sorte, comme si par magie, l'application n'a grandir et maintenant il y a des millions d'enregistrements dans au moins un de ces domaines où plus lignes sont ASCII standard, mais certains contiennent des caractères Unicode sorte que vous devez garderNVARCHAR
, considérez les points suivants:Si vous utilisez SQL Server 2008 - 2016 RTM et sont sur Enterprise Edition, OU si vous utilisez SQL Server 2016 SP1 (qui fait de la Compression des Données disponibles dans toutes les éditions) ou une version plus récente, vous pouvez activer La Compression De Données. La Compression de données peut (mais ne pas "toujours") compresser les données Unicode dans
NCHAR
etNVARCHAR
champs. Les facteurs déterminants sont:NCHAR(1 - 4000)
etNVARCHAR(1 - 4000)
utiliser le Schéma de Compression Standard Unicode, mais seulement à partir de SQL Server 2008 R2, ET seulement DANS la LIGNE de données, pas de DÉBORDEMENT! Cela semble être mieux que l'ordinaire de lignes /PAGE algorithme de compression.NVARCHAR(MAX)
etXML
(et je suppose aussiVARBINARY(MAX)
,TEXT
, etNTEXT
) à des données EN LIGNE (pas de ligne de MÉTIER ou de DÉBORDEMENT de pages) peuvent au moins être compressé, mais pas LIGNE comprimé. Bien sûr, la PAGE de compression dépend de la taille de l'en-ligne valeur: j'ai testé avec VARCHAR(MAX) et vu que 6000 caractères/octet lignes ne serait pas compresser, mais 4000 caractères/octet lignes n'.Si vous utilisez SQL Server 2005 ou 2008 - 2016 RTM et pas sur Enterprise Edition, vous pouvez avoir deux champs: l'un
VARCHAR
et unNVARCHAR
. Par exemple, disons que vous êtes stocker les Url qui sont pour la plupart de la base de caractères ASCII (valeurs de 0 - 127) et donc de s'insérer dansVARCHAR
, mais ont parfois des caractères Unicode. Votre schéma peut inclure les éléments suivants 3 champs:Dans ce modèle vous seulement SÉLECTIONNER à partir de la
[URL]
colonne calculée. Pour l'insertion et la mise à jour, vous de déterminer qui est le champ par voir si la conversion en modifie la valeur entrante, qui doit être deNVARCHAR
type:Vous pouvez GZIP entrant des valeurs dans
VARBINARY(MAX)
et de les décompresser sur le moyen de sortir:COMPRESS
etDECOMPRESS
fonctions, qui sont également GZip.Si vous utilisez SQL Server 2017 ou plus récent, vous pouvez regarder dans la table, un Index Columnstore Cluster.
Alors que ce n'est pas une option viable encore, SQL Server 2019 introduit la prise en charge native pour l'UTF-8 dans
VARCHAR
/CHAR
les types de données. Il y a actuellement trop de bugs avec elle pour lui pour être utilisés, mais s'ils sont fixes, alors c'est une option pour certains scénarios. Veuillez voir mon post, "Natif de l'UTF-8 est pris en charge dans SQL Server 2019: Sauveur ou Faux Prophète?", pour une analyse détaillée de cette nouvelle fonctionnalité.Pour votre application, nvarchar est bien parce que la taille de base de données est petit. En disant "toujours utiliser le type de données nvarchar" est une grande simplification. Si vous n'êtes pas obligé de stocker des choses comme des Kanji ou d'autres personnages loufoques, l'utilisation de type VARCHAR, il va utiliser beaucoup moins d'espace. Mon prédécesseur à mon emploi actuel conçu quelque chose à l'aide de type NVARCHAR quand il n'était pas nécessaire. Nous avons récemment mis en VARCHAR et enregistré 15 GO sur la table (il était très écrites). En outre, si vous avez alors un index sur la table et vous souhaitez inclure cette colonne ou d'en faire un indice composite, vous avez tout à fait votre indice de taille de fichier plus importante.
Juste être sérieux dans votre décision; dans SQL de développement et de définitions de données, il semble rarement être un "défaut de réponse" (autre que d'éviter les curseurs à tous les frais, bien sûr).
Depuis votre application est petite, il n'y a pratiquement pas sensible augmentation des coûts à l'aide de nvarchar plus de varchar, et que vous enregistrez vous-même le potentiel de maux de tête en bas de la route si vous avez besoin de stocker des données unicode.
En général; Commencer avec le plus cher de type de données qui a le moins de contraintes. La mise en production d'. Si la performance commence à être un problème, ce qui est réellement stocké dans ces
nvarchar
colonnes. Est-il des personnages qui ne rentre pas dansvarchar
? Si non, passez en varchar. N'essayez pas de pré-optimiser avant que vous savez où la douleur est. Ma conjecture est que le choix entre nvarchar/varchar n'est pas ce qui va ralentir votre application dans le foreseable avenir. Il y aura d'autres parties de l'application où l'optimisation des performances vous donnera beaucoup plus de bang for the bucks.Pour que les quelques dernières années, tous nos projets ont utilisé NVARCHAR pour tout, depuis tous ces projets sont multilingues. L'import de données à partir de sources externes (par exemple, un fichier ASCII, etc.) est-converti en Unicode avant d'être inséré dans la base de données.
Je n'ai pas encore rencontrer des problèmes liés aux performances de la plus grande indices, etc. Les indices ne utiliser plus de mémoire, mais la mémoire n'est pas cher.
Si vous utilisez des procédures stockées ou construire SQL à la volée s'assurer que toutes les constantes de chaîne avec le préfixe N (par exemple SET @foo = N'Hello monde".;) si la constante est également Unicode. Ceci permet d'éviter tout type de chaîne de conversion au moment de l'exécution.
YMMV.
Je peux parler d'expérience sur ce, méfiez-vous des
nvarchar
. Sauf si vous avez absolument besoin de ces données type de champ détruit la performance sur la base de données plus importante. J'ai hérité d'une base de données qui était mal en termes de performances et de l'espace. Nous avons été en mesure de réduire de 30 go de données dans la taille de 70%! Il y avait quelques autres modifications apportées à l'aide de la performance, mais je suis sûr que levarchar
s'ont aidé de façon significative avec que ainsi. Si votre base de données a le potentiel pour la croissance des tables de un million de + enregistrements rester à l'écart denvarchar
à tout prix.Je m'occupe de cette question au travail souvent:
FTP flux de stocks et les prix - les descriptions de poste et d'autres textes ont été dans nvarchar quand varchar a bien fonctionné. La conversion de ces varchar réduire la taille du fichier de presque de moitié et a vraiment aidé avec le téléchargement.
Le scénario ci-dessus a bien fonctionné jusqu'à ce que quelqu'un a mis un caractère spécial dans la description de l'objet (peut-être de la marque, ne peut pas se souvenir)
Je n'ai pas encore utiliser nvarchar chaque fois plus de type varchar. Si il y a un doute ou un potentiel de caractères spéciaux, j'utilise de type nvarchar. Je trouve que j'utilise varchar plupart du temps quand je suis dans le contrôle à 100% de ce qui est de peupler le champ.
Pourquoi, dans toute cette discussion, il n'y a aucune mention de l'UTF-8? Être capable de stocker de l'unicode complète durée de caractères ne pas dire qu'on doit toujours attribuer deux octets par caractère (ou "code" point d'utilisation de l'UNICODE terme). L'ensemble de l'ASCII est UTF-8. SQL Server vérifie VARCHAR() de champs que le texte est stricte ASCII (c'est à dire en haut de l'octet bit zéro)? J'espère que non.
Si vous souhaitez stocker unicode et veulent la compatibilité avec les anciens ASCII-seules les demandes, je pense que l'utilisation d'VARCHAR() et UTF-8 serait la solution miracle: Il n'utilise plus d'espace quand il en a besoin.
Pour ceux peu familiers avec l'encodage UTF-8, je pourrais recommander une couche d'apprêt.
N
préfixé types). Vous n'obtenez pas un choix de l'utilisation de l'UTF-8. Aussi, les codages Unicode (UTF-8, UCS-2 ET UTF-16 et UTF-32) ne peut pas être appliquée à des champs VARCHAR.Il va y avoir des circonstances exceptionnelles, quand vous voulez délibérément de restreindre le type de données pour s'assurer qu'il n'est pas contenir des caractères à partir d'un certain ensemble. Par exemple, j'avais un scénario où je devais stocker le nom de domaine dans une base de données. L'Internationalisation des noms de domaine n'était pas fiable, à l'époque, il était donc préférable de limiter l'entrée au niveau de la base, et d'aider à éviter les problèmes potentiels.
Si vous utilisez
NVARCHAR
simplement parce qu'une procédure stockée système l'exige, le plus fréquent étant inexplicablementsp_executesql
, et votre SQL dynamique est très longue, vous feriez mieux de partir du point de vue des performances de faire toutes les manipulations de chaînes (concaténation, remplacement, etc.) dansVARCHAR
puis en convertissant le résultat finalNVARCHAR
et l'introduire dans le proc paramètre. Donc, non, ne les utilisent pas toujoursNVARCHAR
!