Verwenden von varchar (MAX) vs TEXT unter SQL Server

195

Ich habe gerade gelesen, dass der VARCHAR(MAX)Datentyp (der fast 2 GB Zeichendaten speichern kann) der empfohlene Ersatz für den TEXTDatentyp in den Versionen SQL Server 2005 und Next SQL SERVER ist.

Welche Operation ist schneller, wenn ich in einer Spalte nach einer Zeichenfolge suchen möchte?

  1. Verwenden Sie eine LIKEKlausel gegen eine VARCHAR(MAX)Spalte?

    WHERE COL1 LIKE '%search string%'

  2. Verwenden Sie die TEXTSpalte und fügen Sie einen Volltextindex / Katalog in diese Spalte ein, und suchen Sie dann mit der CONTAINSKlausel?

    WHERE CONTAINS (Col1, 'MyToken')

user85116
quelle
1
Dieser Beitrag ist auch hilfreich: stackoverflow.com/questions/564755/…
Jake
24
Die wichtigste Erwähnung in diesem Beitrag ist ein Link zur MSDN-Dokumentation , aus der hervorgeht, dass TEXTund NTEXT(und IMAGE) veraltet sind.
Brian
Schauen Sie sich den Link an: stackoverflow.com/q/28980502/1805776
vicky

Antworten:

315

Der VARCHAR(MAX)Typ ist ein Ersatz für TEXT. Der grundlegende Unterschied besteht darin, dass ein TEXTTyp die Daten immer in einem Blob speichert, während der VARCHAR(MAX)Typ versucht, die Daten direkt in der Zeile zu speichern, es sei denn, er überschreitet die 8k-Beschränkung und speichert sie zu diesem Zeitpunkt in einem Blob.

Die Verwendung der LIKE-Anweisung ist zwischen den beiden Datentypen identisch. Die zusätzliche Funktionalität VARCHAR(MAX)besteht darin, dass es auch mit =und GROUP BYwie jede andere VARCHARSpalte verwendet werden kann. Wenn Sie jedoch über viele Daten verfügen, treten bei diesen Methoden große Leistungsprobleme auf.

In Bezug darauf, ob Sie LIKEfür die Suche verwenden sollten oder ob Sie die Volltextindizierung und verwenden sollten CONTAINS. Diese Frage ist unabhängig von VARCHAR(MAX)oder gleich TEXT.

Wenn Sie große Textmengen suchen und die Leistung entscheidend ist, sollten Sie einen Volltextindex verwenden .

LIKE ist einfacher zu implementieren und eignet sich häufig für kleine Datenmengen, weist jedoch aufgrund der Unfähigkeit, einen Index zu verwenden, eine extrem schlechte Leistung bei großen Datenmengen auf.

Robin Day
quelle
12
Ich wusste nicht, dass es bei 8k auf der Seite gespeichert werden würde, und wenn es größer wäre, außerhalb der Seite. Sehr cool.
Brain2000
3
Ihre letzte Zeile ist teilweise falsch. LIKE kann den Index NUR verwenden, wenn sich der Platzhalter am Anfang der Zeichenfolge befindet, nach der gesucht wird.
SouravA
1
Ist es kein Problem, ein Feld von einem Text zu einem Varchar (max) aus einer vorhandenen Tabelle mit Daten zu ändern?
Benutzer1531040
17

Für großen Text, der Volltextindex ist viel schneller. Sie können aber auch einen Volltextindex erstellen varchar(max) .

Joel Coehoorn
quelle
16

Sie können ein Textfeld nicht durchsuchen, ohne es von Text in Varchar zu konvertieren.

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'

Dies gibt einen Fehler:

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

Wobei dies nicht:

declare @table table (a varchar(max))

Interessanterweise LIKEfunktioniert immer noch, dh

where a like '%a%'
DForck42
quelle
11
+1 nur für zufällige Ablehnung! Macht mich verrückt, wenn Leute mich ablehnen und keinen Kommentar haben, sie müssen wirklich ein Leben bekommen.
Tom Stickel
3
Der Grund, warum er Abstimmungen erhielt, ist, dass das, woran ich mich erinnere, kein gültiges Argument für die Beantwortung einer technischen Frage ist. Denken Sie an Leute (wie ich gerade), die versuchen herauszufinden, warum wir varchar(n)oder verwenden sollten text, und über diese Antwort hinwegkommen . Denken Sie in einem professionellen Umfeld, dass das Streiten mit vagen Aussagen zur Lösung des Problems beiträgt? Alle Beiträge auf StackOverflow sollen von Tausenden von Menschen gesehen werden, die Konsequenzen haben!
Anwar
3
@Zeratops lol, diese Antwort ist 6 Jahre alt, ich war ziemlich grün, als ich sie schrieb. Ich habe den Wortlaut aufgeräumt, um mehr auf den Punkt zu bringen.
DForck42
9
  • Grundlegende Definition

TEXTund VarChar(MAX)sind Nicht-Unicode-Zeichen mit großer variabler Länge, die maximal 2147483647 Nicht-Unicode-Zeichen speichern können (dh die maximale Speicherkapazität beträgt: 2 GB).

  • Welches verwenden?

Wie pro MSDN Link schlägt Microsoft mit dem Textdatentyp zu vermeiden , und es wird in zukünftigen Versionen von SQL Server entfernt. Varchar (Max) ist der vorgeschlagene Datentyp zum Speichern der großen Zeichenfolgenwerte anstelle des Textdatentyps.

  • In-Row- oder Out-of-Row-Speicher

Daten einer TextTypspalte werden außerhalb der Zeile auf separaten LOB-Datenseiten gespeichert. Die Zeile auf der Tabellendatenseite enthält nur einen 16-Byte-Zeiger auf die LOB-Datenseite, auf der die tatsächlichen Daten vorhanden sind. Während Daten einer Varchar(max)Typspalte in einer Zeile gespeichert werden, wenn sie kleiner oder gleich 8000 Byte sind. Wenn der Varchar (max) -Spaltenwert die 8000 Bytes überschreitet, wird der Varchar (max) -Spaltenwert in separaten LOB-Datenseiten gespeichert, und die Zeile enthält nur einen 16-Byte-Zeiger auf die LOB-Datenseite, auf der die tatsächlichen Daten vorhanden sind. So In-RowVarchar (Max) ist gut für die Suche und den Abruf.

  • Unterstützte / nicht unterstützte Funktionen

Einige der Zeichenfolgenfunktionen, Operatoren oder Konstrukte funktionieren nicht in der Spalte Texttyp, aber in der Spalte VarChar (Max).

  1. = Entspricht dem Operator in der Spalte vom Typ VarChar (Max)
  2. Gruppieren nach Klausel in der Spalte vom Typ VarChar (Max)

    • Überlegungen zu System-E / A.

Da wir wissen, dass die Spaltenwerte vom Typ VarChar (Max) nur dann außerhalb der Zeile gespeichert werden, wenn die Länge des darin zu speichernden Werts größer als 8000 Byte ist oder nicht genügend Speicherplatz in der Zeile vorhanden ist, wird sie sonst gespeichert es in Reihe. Wenn also die meisten in der Spalte VarChar (Max) gespeicherten Werte groß und außerhalb der Zeile gespeichert sind, ähnelt das Datenabrufverhalten fast dem der Spalte Texttyp.

Wenn jedoch die meisten in Spalten vom Typ VarChar (Max) gespeicherten Werte klein genug sind, um in Zeilen gespeichert zu werden. Das Abrufen der Daten, in denen LOB-Spalten nicht enthalten sind, erfordert dann, dass mehr Datenseiten gelesen werden, da der LOB-Spaltenwert in derselben Datenseite in Zeile gespeichert wird, in der die Nicht-LOB-Spaltenwerte gespeichert sind. Wenn die Auswahlabfrage jedoch eine LOB-Spalte enthält, muss im Vergleich zu den Spalten vom Typ Text weniger Seiten für den Datenabruf gelesen werden.

Fazit

Verwenden Sie den VarChar(MAX)Datentyp anstelle TEXTeiner guten Leistung.

Quelle

Somnath Muluk
quelle
5

Wenn Sie MS Access verwenden (insbesondere ältere Versionen wie 2003), müssen Sie den TEXTDatentyp unter SQL Server verwenden, da MS Access in Access kein Memofeld erkennt nvarchar(MAX), während TEXTes als Memofeld erkannt wird.

Klaus Oberdalhoff
quelle