Utilisation de varchar (MAX) vs TEXT sur SQL Server

195

Je viens de lire que le VARCHAR(MAX)type de données (qui peut stocker près de 2 Go de données de caractères) est le remplacement recommandé pour le TEXTtype de données dans les versions SQL Server 2005 et Next SQL SERVER.

Si je veux rechercher une chaîne dans une colonne, quelle opération est la plus rapide?

  1. Vous utilisez la LIKEclause contre une VARCHAR(MAX)colonne?

    WHERE COL1 LIKE '%search string%'

  2. Utiliser la TEXTcolonne et placer un index / catalogue de texte intégral sur cette colonne, puis effectuer une recherche à l'aide de la CONTAINSclause?

    WHERE CONTAINS (Col1, 'MyToken')

user85116
la source
1
Ce message est également utile: stackoverflow.com/questions/564755/…
Jake
24
La mention la plus importante dans cet article est un lien vers la documentation MSDN montrant que TEXTet NTEXT(et IMAGE) sont déconseillés.
Brian
Regardez le lien: stackoverflow.com/q/28980502/1805776
vicky

Réponses:

315

Le VARCHAR(MAX)type remplace TEXT. La différence fondamentale est qu'un TEXTtype stockera toujours les données dans un blob alors que leVARCHAR(MAX) type tentera de stocker les données directement dans la ligne à moins qu'il ne dépasse la limite de 8k et qu'à ce moment il les stocke dans un blob.

L'utilisation de l'instruction LIKE est identique entre les deux types de données. La fonctionnalité supplémentaire que VARCHAR(MAX)vous donne est qu'elle peut également être utilisée avec =et GROUP BYcomme n'importe quelle autre VARCHARcolonne. Cependant, si vous avez beaucoup de données, vous aurez un énorme problème de performances en utilisant ces méthodes.

En ce qui concerne si vous devez utiliser LIKEpour rechercher, ou si vous devez utiliser l' indexation de texte intégral et CONTAINS. Cette question est la même indépendamment de VARCHAR(MAX)ou TEXT.

Si vous recherchez de grandes quantités de texte et que les performances sont essentielles, vous devez utiliser un index de texte intégral .

LIKE est plus simple à mettre en œuvre et convient souvent à de petites quantités de données, mais ses performances sont extrêmement médiocres avec des données volumineuses en raison de son incapacité à utiliser un index.

Robin Day
la source
12
Je ne savais pas qu'il serait stocké dans la page à 8 Ko et hors de la page s'il était plus grand. Très cool.
Brain2000
3
Votre dernière ligne est partiellement fausse. LIKE ne peut pas utiliser l'index UNIQUEMENT si le caractère générique se trouve au début de la chaîne recherchée.
SouravA
1
N'est-ce pas un problème de modifier un champ d'un texte en un varchar (max) d'une table existante avec des données?
user1531040
17

Pour le texte volumineux, l' index de texte intégral est beaucoup plus rapide. Mais vous pouvez également indexer le texte intégral varchar(max) .

Joel Coehoorn
la source
16

Vous ne pouvez pas rechercher un champ de texte sans le convertir du texte en varchar.

declare @table table (a text)
insert into @table values ('a')
insert into @table values ('a')
insert into @table values ('b')
insert into @table values ('c')
insert into @table values ('d')


select *
from @table
where a ='a'

Cela donne une erreur:

The data types text and varchar are incompatible in the equal to operator.

Alors que cela ne signifie pas:

declare @table table (a varchar(max))

Fait intéressant, LIKEfonctionne toujours, à savoir

where a like '%a%'
DForck42
la source
11
+1 juste pour avoir dit un downvote aléatoire! Ça me rend fou quand les gens me dévalorisent et n'ont aucun commentaire, ils ont vraiment besoin de vivre.
Tom Stickel
3
La raison pour laquelle il a obtenu des votes négatifs, c'est que d' après ce dont je me souviens des choses que j'ai dû faire, ce n'est pas un argument valable à apporter pour répondre à une question technique. Pensez à des gens (comme moi en ce moment) essayant de comprendre pourquoi devrions-nous utiliser varchar(n)ou text, et surmonter cette réponse. Pensez-vous, dans un environnement professionnel, qu'argumenter avec des déclarations vagues aidera à résoudre le problème? Tous les articles sur StackOverflow sont destinés à être vus par des milliers de personnes, agissez en conséquence!
Anwar
3
@Zeratops lol, cette réponse a 6 ans, j'étais plutôt verte alors quand je l'ai écrite. j'ai nettoyé le libellé pour être plus précis.
DForck42
9
  • Définition de base

TEXTet VarChar(MAX)sont des types de données de caractères à longueur variable non Unicode de grande taille, qui peuvent stocker au maximum 2147483647 caractères non Unicode (c'est-à-dire que la capacité de stockage maximale est de 2 Go).

  • Lequel utiliser?

Selon le lien MSDN, Microsoft suggère d'éviter d'utiliser le type de données Text et il sera supprimé dans les futures versions de Sql Server. Varchar (Max) est le type de données suggéré pour stocker les grandes valeurs de chaîne au lieu du type de données Text.

  • Stockage en ligne ou hors ligne

Les données d'une Textcolonne de type sont stockées hors ligne dans des pages de données LOB distinctes. La ligne de la page de données de table n'aura qu'un pointeur de 16 octets vers la page de données LOB où les données réelles sont présentes. Alors que les données d'une Varchar(max)colonne de type sont stockées en ligne si elles sont inférieures ou égales à 8000 octets. Si la valeur de la colonne Varchar (max) dépasse les 8000 octets, la valeur de la colonne Varchar (max) est stockée dans des pages de données LOB distinctes et la ligne n'aura qu'un pointeur de 16 octets vers la page de données LOB où les données réelles sont présentes. Donc In-RowVarchar (Max) est bon pour les recherches et la récupération.

  • Fonctionnalités prises en charge / non prises en charge

Certaines des fonctions de chaîne, des opérateurs ou des constructions qui ne fonctionnent pas sur la colonne de type Texte, mais elles fonctionnent sur la colonne de type VarChar (Max).

  1. = Égal à l'opérateur sur la colonne de type VarChar (Max)
  2. Clause Group by sur la colonne de type VarChar (Max)

    • Considérations d'E / S système

Comme nous savons que les valeurs de la colonne de type VarChar (Max) sont stockées hors ligne uniquement si la longueur de la valeur à y stocker est supérieure à 8 000 octets ou s'il n'y a pas assez d'espace dans la ligne, sinon elle stockera il en ligne. Ainsi, si la plupart des valeurs stockées dans la colonne VarChar (Max) sont volumineuses et stockées hors ligne, le comportement de récupération des données sera presque similaire à celui de la colonne Type de texte.

Mais si la plupart des valeurs stockées dans les colonnes de type VarChar (Max) sont suffisamment petites pour être stockées en ligne. La récupération des données dans lesquelles les colonnes LOB ne sont pas incluses nécessite plus de pages de données à lire, car la valeur de la colonne LOB est stockée en ligne dans la même page de données où les valeurs des colonnes non LOB sont stockées. Mais si la requête de sélection inclut une colonne LOB, elle nécessite moins de pages à lire pour la récupération des données par rapport aux colonnes de type texte.

Conclusion

Utilisez VarChar(MAX)le type de données plutôt que TEXTpour de bonnes performances.

La source

Somnath Muluk
la source
5

Si vous utilisez MS Access (en particulier les anciennes versions comme 2003), vous êtes obligé d'utiliser le TEXTtype de données sur SQL Server car MS Access ne reconnaît pas nvarchar(MAX)comme un champ Mémo dans Access, alors qu'il TEXTest reconnu comme un champ Mémo.

Klaus Oberdalhoff
la source