Y a-t-il des inconvénients à toujours utiliser nvarchar(MAX)?

dans SQL Server 2005, y a-t-il des inconvénients à rendre tous les champs de caractères nvarchar(MAX) plutôt que de spécifier une longueur explicitement, par exemple nvarchar(255)? (Mis à part le fait évident que vous ne pouvez pas limiter la longueur du champ au niveau de la base de données)

307
demandé sur Tim Abell 2008-09-29 16:01:11

22 réponses

même question a été posée sur les Forums MSDN:

à Partir de l'original post (plus d'informations):

lorsque vous stockez des données dans une colonne VARCHAR(N), Les valeurs sont stockées physiquement de la même manière. Mais quand vous le stockez dans une colonne VARCHAR (MAX), derrière l'écran les données sont traitées comme une valeur de texte. Donc, il est un traitement supplémentaire est nécessaire pour traiter une valeur VARCHAR(MAX). (seulement si le calibre est supérieur à 8000)

VARCHAR(MAX) ou de type NVARCHAR(MAX) est considéré comme un "grand type de la valeur'. Les types de grande valeur sont généralement stockés "hors ligne". Cela signifie que la ligne de données ont un pointeur à un endroit où la "grande valeur" est stockée...

134
répondu David Kreps 2016-10-12 07:09:28

C'est une bonne question et il a déclaré en dehors de l'évident...

inconvénients pourraient inclure:

les conséquences de Performance Query optimizer utilise la taille du champ pour déterminer le plan d'exécution le plus efficace

" 1. La répartition de l'espace dans les extensions et les pages de la base de données sont flexibles. Ainsi, lors de l'ajout d'informations dans le champ en utilisant update, votre base de données devra créer un pointeur si les nouvelles données sont plus longues que précédemment insérée. Cela les dossiers de base de données deviendraient fragmentés = la performance inférieure dans presque tout, de l'index à l'effacement, la mise à jour et les inserts. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx

implications D'intégration - difficile pour les autres systèmes de savoir comment s'intégrer à votre base de données Croissance imprévisible des données Problèmes de sécurité possibles, par exemple un plantage du système prenant tout l'espace disque

il y a un bon article ici: http://searchsqlserver.techtarget.com/tip/1,289483, sid87_gci1098157, 00.html

45
répondu alexmac 2013-08-08 11:05:13

parfois, vous voulez que le type de données renforce un certain sens sur les données qu'il contient.

dites par exemple que vous avez une colonne qui ne devrait pas vraiment être plus longue que, disons, 20 caractères. Si vous définissez cette colonne comme VARCHAR (MAX), une application dévoyée pourrait y insérer une longue chaîne et vous ne le sauriez jamais, ou n'auriez aucun moyen de l'empêcher.

La prochaine fois que votre application utilise cette chaîne, sous l'hypothèse que la longueur de la chaîne est modeste et raisonnable pour le domaine qu'il représente, vous connaîtrez un résultat imprévisible et déroutant.

27
répondu Bill Karwin 2009-06-08 19:33:13

D'après le lien fourni dans la réponse acceptée, il semble que:

  1. 100 les caractères stockés dans un champ nvarchar(MAX) ne seront pas stockés différent de 100 caractères dans un champ nvarchar(100) - les données seront stockées en ligne et vous n'aurez pas la charge de la lecture et de l'écriture des données "hors ligne". Donc pas de soucis.

  2. si la taille est supérieure à 4000 les données seraient stockées 'hors ligne', qui est ce que vous voulez. Donc pas de soucis non plus.

However...

  1. vous ne pouvez pas créer un index sur une colonne nvarchar(MAX) . Vous pouvez utiliser l'indexation en texte intégral, mais vous ne pouvez pas créer un index sur la colonne pour améliorer la performance de requête. Pour moi, cela scelle l'affaire...c'est un désavantage certain d'utiliser toujours nvarchar(MAX).

Conclusion:

si vous voulez une sorte de" longueur de chaîne universelle "dans toute votre base de données, qui peut être indexée et qui ne gaspille pas d'espace et de temps d'accès, alors vous pouvez utiliser nvarchar(4000) .

19
répondu Tim Abell 2016-03-13 15:47:59

j'ai vérifié quelques articles et trouver le script de test utile de ceci: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Puis je l'ai changé pour comparer entre NVARCHAR(10) vs nvarchar(4000) vs NVARCHAR(MAX) et je ne trouve pas de différence de vitesse en utilisant des nombres spécifiés mais en utilisant MAX. Vous pouvez tester par vous-même. Espérons que Cette aide.

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
17
répondu QMaster 2016-08-17 09:19:04

pensez - y comme un autre niveau de sécurité. Vous pouvez concevoir votre table sans relations étrangères clés-parfaitement valide - et assurer l'existence d'entités associées entièrement sur la couche d'affaires. Toutefois, les clés étrangères sont considérées comme de bonnes pratiques de conception parce qu'elles ajoutent un autre niveau de contrainte au cas où quelque chose se dérègle dans la couche des affaires. Il en va de même pour la limitation de la taille du champ et la non-utilisation de varchar MAX.

12
répondu Alex 2009-06-08 19:37:37

une raison de ne pas utiliser les champs max ou texte est que vous ne pouvez pas effectuer l'index en ligne reconstruit c.-à-d. reconstruire avec ONLINE= ON, même avec SQL Server Enterprise Edition.

8
répondu Nick Kavadias 2009-06-08 20:36:18

le seul problème que j'ai trouvé était que nous développons nos applications sur SQL Server 2005, et dans un cas, nous devons prendre en charge SQL Server 2000. Je viens d'apprendre, le hard way que SQL Server 2000 n'aime pas L'option MAX pour varchar ou nvarchar.

4
répondu mattruma 2008-09-29 12:11:17

mauvaise idée quand vous savez que le champ sera dans un ensemble de 5 à 10 caractères par exemple. Je pense que je n'utiliserais max que si je n'étais pas sûr de la longueur. Par exemple, un numéro de téléphone ne serait jamais plus qu'un certain nombre de caractères.

pouvez-vous honnêtement dire que vous n'êtes pas certain de la longueur approximative requise pour chaque champ de votre table?

je comprends votre point de vue cependant - il ya des domaines, Je ne doute pas envisagez d'utiliser varchar (max).

il est intéressant de noter que le MSDN docs résume assez bien:

utiliser varchar lorsque les tailles de la les entrées de données de colonne varient considérablement. Utilisez varchar (max) lorsque les tailles de la les entrées de données de colonne varient considérablement, et la taille pourrait dépasser 8 000 octets.

il y a une discussion intéressante sur la question ici .

4
répondu RichardOD 2009-06-08 19:36:10

le travail de la base de données est de stocker des données afin qu'elles puissent être utilisées par l'entreprise. Pour rendre ces données utiles, il faut notamment veiller à ce qu'elles soient significatives. Permettre à quelqu'un d'entrer un nombre illimité de caractères pour son prénom ne garantit pas des données significatives.

intégrer ces contraintes dans la couche affaires est une bonne idée, mais cela ne garantit pas que la base de données restera intacte. La seule façon de garantir que les données les règles ne sont pas bafoués pour les appliquer au niveau le plus bas possible dans la base de données.

4
répondu Tom H 2009-06-08 20:49:02

un problème est que si vous devez travailler avec plusieurs versions de SQL Server, LE MAX ne fonctionnera pas toujours. Donc, si vous travaillez avec des DB legacy ou toute autre situation qui implique plusieurs versions, vous feriez mieux d'être très prudent.

3
répondu TheTXI 2009-06-08 19:25:14

comme il a été souligné ci-dessus, il s'agit principalement d'un compromis entre le stockage et la performance. Au moins dans la plupart des cas.

cependant, il y a au moins un autre facteur à prendre en compte lors du choix de n/varchar(Max) par rapport à n/varchar(n). Les données seront-elles indexées (par exemple, un nom de famille)? Puisque la définition de MAX est considérée comme une LOB, alors tout ce qui est défini comme MAX n'est pas disponible pour l'indexation. et sans index, toute recherche impliquant les données prédit dans une clause où va être forcé dans un balayage complet de la Table, qui est la pire performance que vous pouvez obtenir pour les recherches de données.

3
répondu Harry Cooper 2016-08-29 20:40:14

1) le serveur SQL devra utiliser plus de ressources (mémoire allouée et temps cpu) lorsqu'il traite avec nvarchar(max) vs nvarchar(n) où n est un nombre spécifique au champ.

2) qu'est-ce que cela signifie en ce qui concerne la performance?

sur SQL Server 2005, j'ai interrogé 13 000 lignes de données à partir d'une table avec 15 colonnes nvarchar(max). J'ai chronométré les requêtes à plusieurs reprises puis changé les colonnes en nvarchar(255) ou moins.

les requêtes avant l'optimisation sont en moyenne à 2.0858 secondes. Les requêtes postérieures au changement sont revenues en moyenne 1,90 seconde. C'était environ 184 millisecondes d'amélioration à la requête de base select*. C'est une amélioration de 8,8%.

3) Mes résultats sont en accord avec quelques autres articles qui ont indiqué qu'il y avait une différence de rendement. Selon votre base de données et la requête, le pourcentage d'amélioration peut varier. Si vous n'avez pas beaucoup d'utilisateurs concurrents ou beaucoup d'enregistrements, alors la différence de performance ne sera pas un problème pour vous. Toutefois, l'écart de rendement augmentera à mesure que le nombre d'enregistrements et d'utilisateurs concurrents augmentera.

2
répondu WWC 2013-04-29 08:05:41

j'ai eu un udf qui a rembourré les chaînes et mis la sortie à varchar(max). Si on l'utilisait directement au lieu de le ramener à la taille appropriée pour la colonne ajustée, le rendement était très mauvais. J'ai fini par mettre l'udf à une longueur arbitraire avec une grosse note au lieu de compter sur tous les appelants de l'udf pour rejouer la chaîne à une taille plus petite.

1
répondu Cade Roux 2008-09-29 12:29:47

lien Intéressant: Pourquoi utiliser un VARCHAR lorsque vous pouvez utiliser du TEXTE?

il s'agit de PostgreSQL et MySQL, donc l'analyse de performance est différente, mais la logique de "explicitness" tient toujours: pourquoi vous forcer à toujours vous soucier de quelque chose qui est pertinent un petit pourcentage du temps? Si vous avez sauvegardé une adresse email vers une variable, vous utiliserez une 'string' et non une 'string limitée à 80 caractères'.

1
répondu orip 2008-11-12 17:46:29

héritage système de soutien. Si vous avez un système qui utilise les données et il devrait être d'une certaine longueur, puis la base de données est un bon endroit pour faire respecter la longueur. Ce n'est pas idéal, mais les anciens systèmes ne le sont pas toujours. = P

1
répondu Tony 2009-06-08 19:39:22

si toutes les données d'une rangée (pour toutes les colonnes) ne prennent pas raisonnablement 8000 caractères ou moins, alors la conception à la couche de données devrait renforcer cela.

le moteur de base de données est beaucoup plus efficace en gardant tout hors du stockage blob. Le plus vous pouvez restreindre ligne le mieux. Plus le nombre de lignes que vous pouvez fourrer dans une page le mieux. La base de données fonctionne mieux quand elle doit accéder à moins de pages.

1
répondu Matt Spradley 2009-06-08 19:59:10

mes tests ont montré qu'il y a des différences lors de la sélection.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;
1
répondu Kvasi 2016-09-30 10:36:43

le principal inconvénient que je peux voir est que disons que vous avez ceci:

Qui vous donne le plus d'informations sur les données nécessaires pour l'INTERFACE utilisateur?

Ce

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Ou Ça?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]
0
répondu carlos martini 2012-04-17 17:21:02

un inconvénient est que vous allez concevoir autour d'une variable imprévisible, et vous allez probablement ignorer au lieu de profiter de la structure de données interne du serveur SQL, progressivement constituée de ligne(s), Page(s), et étendue(s).

ce qui me fait penser à alignement de la structure de données en C, et que le fait d'être conscient de l'alignement est généralement considéré comme une bonne chose (TM). Idée similaire, contexte différent.

page MSDN pour les Pages et les Extensions

page MSDN pour Données de Dépassement de Ligne

0
répondu tsundoku 2012-08-04 16:05:51

cela va causer un problème de performance, bien qu'il ne puisse jamais causer de problèmes réels si votre base de données est petite. Chaque enregistrement prendra plus d'espace sur le disque dur et la base de données aura besoin de lire plus de secteurs du disque si vous cherchez à travers un grand nombre d'enregistrements à la fois. Par exemple, un petit enregistrement pourrait correspondre à 50 pour un secteur et un grand enregistrement pourrait correspondre à 5. Vous devez lire 10 fois plus de données du disque en utilisant le grand enregistrement.

-1
répondu Dan Goldstein 2008-09-29 12:32:35

il rendra la conception de l'écran plus difficile que vous ne serez plus en mesure de prédire la largeur de vos contrôles devraient être.

-3
répondu pappes 2008-09-29 12:33:03