Utilizzo di varchar (MAX) vs TEXT su SQL Server


196

Ho appena letto che il VARCHAR(MAX)tipo di dati (che può contenere quasi 2 GB di dati char) è la sostituzione consigliata per il TEXTtipo di dati nelle versioni SQL Server 2005 e Next SQL SERVER.

Se voglio cercare una stringa all'interno di una colonna, quale operazione è più veloce?

  1. Usando una LIKEclausola contro una VARCHAR(MAX)colonna?

    WHERE COL1 LIKE '%search string%'

  2. Utilizzando la TEXTcolonna e inserire un indice / catalogo full-text su questa colonna, quindi cercare utilizzando la CONTAINSclausola?

    WHERE CONTAINS (Col1, 'MyToken')


1
Questo post è anche utile: stackoverflow.com/questions/564755/…
Jake

26
La menzione più importante in quel post è un collegamento alla documentazione MSDN che mostra che TEXTe NTEXT(e IMAGE) sono deprecati.
Brian,

Risposte:


316

Il VARCHAR(MAX)tipo è un sostituto di TEXT. La differenza di base è che un TEXTtipo memorizzerà sempre i dati in un BLOB mentre il VARCHAR(MAX)tipo tenterà di archiviare i dati direttamente nella riga a meno che non superi la limitazione di 8k e a quel punto li memorizzi in un BLOB.

L'uso dell'istruzione LIKE è identico tra i due tipi di dati. La funzionalità aggiuntiva VARCHAR(MAX)ti dà è che può anche essere utilizzata con =e GROUP BYcome qualsiasi altra VARCHARcolonna può essere. Tuttavia, se disponi di molti dati, avrai questi enormi problemi di prestazioni usando questi metodi.

Per quanto riguarda se è necessario utilizzare LIKEper la ricerca o se è necessario utilizzare l' indicizzazione di testo completo e CONTAINS. Questa domanda è la stessa indipendentemente da VARCHAR(MAX)o TEXT.

Se stai cercando grandi quantità di testo e le prestazioni sono fondamentali, devi utilizzare un indice di testo completo .

LIKE è più semplice da implementare ed è spesso adatto a piccole quantità di dati, ma ha prestazioni estremamente scarse con dati di grandi dimensioni a causa della sua incapacità di utilizzare un indice.


12
Non sapevo che sarebbe memorizzato nella pagina a 8k, e fuori dalla pagina se più grande. Molto bello.
Brain2000,

3
L'ultima riga è parzialmente errata. LIKE non può utilizzare l'indice SOLO se il carattere jolly si trova all'inizio della stringa da cercare.
SouravA,

1
Non è un problema modificare un campo da un testo a un varchar (max) da una tabella esistente con dati?
user1531040,

17

Per testi di grandi dimensioni, l' indice di testo completo è molto più veloce. Ma puoi anche indicizzare il testo completo varchar(max) .


16

Non è possibile cercare un campo di testo senza convertirlo da testo a 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'

Questo dà un errore:

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

Laddove ciò non:

declare @table table (a varchar(max))

È interessante notare LIKEche funziona ancora, vale a dire

where a like '%a%'

11
+1 solo per dire downvote casuale! Mi fa impazzire quando le persone mi votano e non hanno commenti, hanno davvero bisogno di avere una vita.
Tom Stickel,

3
Il motivo per cui ha ottenuto i voti negativi è che da ciò che ricordo dalle cose che ho dovuto fare non è un argomento valido da portare quando si risponde a una domanda tecnica. Pensa alle persone (come me in questo momento) che cercano di capire perché dovremmo usare varchar(n)o texte superare questa risposta. Pensi, in un ambiente professionale, che discutere con dichiarazioni vaghe aiuterà a risolvere il problema? Tutti i post su StackOverflow sono fatti per essere visti da migliaia di persone, agire in conseguenza!
Anwar,

3
@Zeratops lol, questa risposta ha 6 anni, ero piuttosto verde per così quando l'ho scritto. ho ripulito il testo per essere più al punto.
DForck42,

9
  • Definizione di base

TEXTe VarChar(MAX)sono tipi di dati di carattere di lunghezza variabile non Unicode di grandi dimensioni, che possono contenere un massimo di 2147483647 caratteri non Unicode (ovvero la capacità massima di archiviazione è: 2 GB).

  • Quale usare?

Come da collegamento MSDN, Microsoft suggerisce di evitare l'utilizzo del tipo di dati Text e verrà rimosso in una versione futura di SQL Server. Varchar (Max) è il tipo di dati suggerito per la memorizzazione dei valori di stringa di grandi dimensioni invece del tipo di dati Testo.

  • Archiviazione In-Row o Out-of-Row

I dati di una Textcolonna di tipo vengono archiviati fuori riga in pagine di dati LOB separate. La riga nella pagina dei dati della tabella avrà solo un puntatore di 16 byte alla pagina dei dati LOB in cui sono presenti i dati effettivi. Mentre i dati di una Varchar(max)colonna di tipo vengono archiviati nella riga se è inferiore o uguale a 8000 byte. Se il valore della colonna Varchar (max) attraversa gli 8000 byte, il valore della colonna Varchar (max) viene archiviato in pagine di dati LOB separate e la riga avrà solo un puntatore di 16 byte alla pagina di dati LOB in cui sono presenti i dati effettivi. Quindi In-RowVarchar (Max) è buono per le ricerche e il recupero.

  • Funzionalità supportate / non supportate

Alcune funzioni stringa, operatori o costrutti che non funzionano sulla colonna Tipo testo, ma funzionano sulla colonna Tipo VarChar (Max).

  1. = Uguale a Operatore nella colonna di tipo VarChar (Max)
  2. Raggruppa per clausola sulla colonna di tipo VarChar (Max)

    • Considerazioni sull'IO del sistema

Come sappiamo che i valori di colonna del tipo VarChar (Max) sono memorizzati fuori riga solo se la lunghezza del valore da archiviare è maggiore di 8000 byte o non c'è abbastanza spazio nella riga, altrimenti memorizzerà in fila. Quindi, se la maggior parte dei valori memorizzati nella colonna VarChar (Max) sono grandi e archiviati fuori riga, il comportamento di recupero dei dati sarà quasi simile a quello della colonna Tipo di testo.

Ma se la maggior parte dei valori memorizzati nelle colonne di tipo VarChar (Max) sono abbastanza piccoli da essere archiviati in fila. Quindi il recupero dei dati in cui le colonne LOB non sono incluse richiede il numero maggiore di pagine di dati da leggere poiché il valore della colonna LOB viene archiviato in fila nella stessa pagina di dati in cui sono memorizzati i valori delle colonne non LOB. Ma se la query di selezione include la colonna LOB, richiede un numero inferiore di pagine da leggere per il recupero dei dati rispetto alle colonne del tipo di testo.

Conclusione

Utilizzare il VarChar(MAX)tipo di dati anziché TEXTper una buona prestazione.

fonte


5

Se si utilizza MS Access (in particolare versioni precedenti come 2003), si è costretti a utilizzare il TEXTtipo di dati su SQL Server poiché MS Access non riconosce nvarchar(MAX)come campo Memo in Access, mentre TEXTviene riconosciuto come campo Memo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.