Usando varchar (MAX) vs TEXT no SQL Server

195

Acabei de ler que o VARCHAR(MAX)tipo de dados (que pode armazenar perto de 2 GB de dados de caracteres) é a substituição recomendada para o TEXTtipo de dados nas versões SQL Server 2005 e Next SQL SERVER.

Se eu quiser procurar dentro de uma coluna qualquer string, qual operação é mais rápida?

  1. Usando uma LIKEcláusula the contra uma VARCHAR(MAX)coluna?

    WHERE COL1 LIKE '%search string%'

  2. Usando a TEXTcoluna, coloque um Índice / Catálogo de Texto Completo nessa coluna e pesquise usando a CONTAINScláusula?

    WHERE CONTAINS (Col1, 'MyToken')

user85116
fonte
1
Esta publicação também é útil: stackoverflow.com/questions/564755/…
Jake
24
A menção mais importante nessa postagem é um link para a documentação do MSDN mostrando que TEXTe NTEXT(e IMAGE) estão obsoletos.
27711 Brian

Respostas:

315

O VARCHAR(MAX)tipo é um substituto para TEXT. A diferença básica é que um TEXTtipo sempre armazena os dados em um blob, enquanto o VARCHAR(MAX)tipo tenta armazenar os dados diretamente na linha, a menos que exceda a limitação de 8k e nesse ponto os armazena em um blob.

O uso da instrução LIKE é idêntico entre os dois tipos de dados. A funcionalidade adicional VARCHAR(MAX)fornece a você que também pode ser usada com =e GROUP BYcomo qualquer outra VARCHARcoluna. No entanto, se você tiver muitos dados, terá um enorme problema de desempenho usando esses métodos.

Em relação a se você deve usar LIKEpara pesquisar ou se deve usar a Indexação de Texto Completo e CONTAINS. Esta pergunta é a mesma, independentemente de VARCHAR(MAX)ou TEXT.

Se você estiver pesquisando grandes quantidades de texto e o desempenho for fundamental, use um Índice de Texto Completo .

LIKE é mais simples de implementar e geralmente é adequado para pequenas quantidades de dados, mas apresenta desempenho extremamente ruim com dados grandes devido à sua incapacidade de usar um índice.

Robin Day
fonte
12
Eu não sabia que ele seria armazenado na página às 8k e fora da página, se maior. Muito legal.
Brain2000
3
Sua última linha está parcialmente errada. LIKE não pode usar SOMENTE o índice se o curinga estiver no início da string que está sendo pesquisada.
SouravA
1
Não é problema alterar um campo de um texto para um varchar (max) de uma tabela existente com dados?
user1531040
17

Para texto grande, o índice de texto completo é muito mais rápido. Mas você também pode indexar o texto completo varchar(max) .

Joel Coehoorn
fonte
16

Você não pode procurar um campo de texto sem convertê-lo de texto para 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'

Isso dá um erro:

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

Onde isso não acontece:

declare @table table (a varchar(max))

Curiosamente, LIKEainda funciona, ou seja,

where a like '%a%'
DForck42
fonte
11
+1 apenas por dizer voto negativo aleatório! Me deixa louca quando as pessoas me criticam e não fazem comentários, elas realmente precisam ter uma vida.
22614 Tom Tomel
3
A razão pela qual ele recebeu votos negativos é que, pelo que me lembro das coisas que tive que fazer, não é um argumento válido a ser apresentado ao responder uma pergunta técnica. Pense nas pessoas (como eu agora) tentando descobrir por que devemos usar varchar(n)ou texte supere essa resposta. Você acha que, em um ambiente profissional, argumentar com declarações vagas ajudará a resolver o problema? Todos os posts no StackOverflow são para serem vistos por milhares de pessoas, agem com consequências!
Anwar
3
@Zeratops lol, esta resposta tem 6 anos, eu era bastante verde quando escrevi. limpei o texto para ser mais direto ao ponto.
DForck42 3/11
9
  • Definição básica

TEXTe VarChar(MAX)são do tipo de dados de caracteres de tamanho variável grande não Unicode, que podem armazenar no máximo 2147483647 caracteres não Unicode (ou seja, a capacidade máxima de armazenamento é de 2 GB).

  • Qual usar?

De acordo com o link do MSDN, a Microsoft sugere evitar o uso do tipo de dados Texto e ele será removido em versões futuras do Sql Server. Varchar (Máx.) É o tipo de dados sugerido para armazenar os valores de cadeia grande em vez do tipo de dados Texto.

  • Armazenamento em linha ou fora de linha

Os dados de uma Textcoluna de tipo são armazenados fora da linha em páginas de dados LOB separadas. A linha na página de dados da tabela terá apenas um ponteiro de 16 bytes para a página de dados LOB em que os dados reais estão presentes. Enquanto a Varchar(max)coluna Dados de um tipo é armazenada em linha, se for menor ou igual a 8000 bytes. Se o valor da coluna Varchar (max) estiver cruzando os 8000 bytes, o valor da coluna Varchar (max) será armazenado em páginas de dados LOB separadas e a linha terá apenas um ponteiro de 16 bytes para a página de dados LOB em que os dados reais estão presentes. Portanto, o In-RowVarchar (Max) é bom para pesquisas e recuperação.

  • Funcionalidades suportadas / não suportadas

Algumas das funções de string, operadores ou construções que não funcionam na coluna Tipo de texto, mas funcionam na coluna do tipo VarChar (Max).

  1. = Igual ao Operador na coluna do tipo VarChar (Max)
  2. Agrupar por cláusula na coluna do tipo VarChar (Max)

    • Considerações sobre System IO

Como sabemos que os valores da coluna do tipo VarChar (Max) são armazenados fora da linha somente se o comprimento do valor a ser armazenado for maior que 8000 bytes ou se não houver espaço suficiente na linha, caso contrário, ele armazenará em linha. Portanto, se a maioria dos valores armazenados na coluna VarChar (Max) forem grandes e armazenados fora da linha, o comportamento de recuperação de dados será quase semelhante ao da coluna Tipo de texto.

Mas se a maioria dos valores armazenados nas colunas do tipo VarChar (Max) forem pequenos o suficiente para armazenar em linha. A recuperação dos dados em que as colunas LOB não estão incluídas requer o maior número de páginas de dados a serem lidas, pois o valor da coluna LOB é armazenado em linha na mesma página de dados em que os valores das colunas não LOB são armazenados. Mas se a consulta de seleção incluir a coluna LOB, será necessário um número menor de páginas para ler para a recuperação de dados em comparação com as colunas do tipo Texto.

Conclusão

Use o VarChar(MAX)tipo de dados e não TEXTpara obter um bom desempenho.

Fonte

Somnath Muluk
fonte
5

Se você estiver usando o MS Access (especialmente versões mais antigas como 2003), será forçado a usar o TEXTtipo de dados no SQL Server, pois o MS Access não reconhece nvarchar(MAX)como um campo Memorando no Access, enquanto TEXTé reconhecido como um campo Memorando.

Klaus Oberdalhoff
fonte