Usando varchar (MAX) vs TEXT en SQL Server

195

Acabo de leer que el VARCHAR(MAX)tipo de datos (que puede almacenar cerca de 2 GB de datos char) es el reemplazo recomendado para el TEXTtipo de datos en las versiones SQL Server 2005 y Next SQL SERVER.

Si deseo buscar dentro de una columna alguna cadena, ¿qué operación es más rápida?

  1. ¿Usando una LIKEcláusula contra una VARCHAR(MAX)columna?

    WHERE COL1 LIKE '%search string%'

  2. ¿Usa la TEXTcolumna y coloca un Índice / Catálogo de texto completo en esta columna, y luego busca usando la CONTAINScláusula?

    WHERE CONTAINS (Col1, 'MyToken')

usuario85116
fuente
1
Esta publicación también es útil: stackoverflow.com/questions/564755/…
Jake
24
La mención más importante en esa publicación es un enlace a la documentación de MSDN que muestra que TEXTy NTEXT(y IMAGE) están en desuso.
Brian
Mira el enlace: stackoverflow.com/q/28980502/1805776
vicky

Respuestas:

315

El VARCHAR(MAX)tipo es un reemplazo para TEXT. La diferencia básica es que un TEXTtipo siempre almacenará los datos en un blob mientras que el VARCHAR(MAX)tipo intentará almacenar los datos directamente en la fila a menos que exceda la limitación de 8k y en ese punto los almacene en un blob.

El uso de la declaración LIKE es idéntico entre los dos tipos de datos. La funcionalidad adicional que VARCHAR(MAX)le brinda es que también se puede usar con =y GROUP BYcomo cualquier otra VARCHARcolumna. Sin embargo, si tiene muchos datos, tendrá un gran problema de rendimiento al usar estos métodos.

Con respecto a si debe usar LIKEpara buscar, o si debe usar la Indización de texto completo y CONTAINS. Esta pregunta es la misma independientemente de VARCHAR(MAX)o TEXT.

Si está buscando grandes cantidades de texto y el rendimiento es clave, entonces debe usar un índice de texto completo .

LIKE es más simple de implementar y a menudo es adecuado para pequeñas cantidades de datos, pero tiene un rendimiento extremadamente pobre con datos grandes debido a su incapacidad para usar un índice.

Día de robin
fuente
12
No sabía que se almacenaría en la página a 8k, y fuera de la página si fuera más grande. Muy genial.
Brain2000
3
Tu última línea está parcialmente equivocada. LIKE no puede usar el índice SOLAMENTE si el comodín está al comienzo de la cadena que se está buscando.
SouravA
1
¿No es un problema alterar un campo de un texto a un varchar (max) de una tabla existente con datos?
user1531040
17

Para texto grande, el índice de texto completo es mucho más rápido. Pero también puede indexar el texto completo varchar(max) .

Joel Coehoorn
fuente
16

No puede buscar un campo de texto sin convertirlo de texto 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'

Esto da un error:

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

Wheras esto no:

declare @table table (a varchar(max))

Curiosamente, LIKEtodavía funciona, es decir

where a like '%a%'
DForck42
fuente
11
¡+1 solo por decir downvote al azar! Me vuelve loco cuando la gente me rechaza y no tiene comentarios, realmente necesitan ganarse la vida.
Tom Stickel
3
La razón por la que recibió votos negativos es que, por lo que recuerdo de las cosas que he tenido que hacer, no es un argumento válido para responder al responder una pregunta técnica. Piensa en las personas (como yo en este momento) tratando de averiguar por qué deberíamos usar varchar(n)o text, y superar esta respuesta. ¿Crees, en un entorno profesional, que discutir con declaraciones vagas ayudará a resolver el problema? ¡Todas las publicaciones en StackOverflow deben ser vistas por miles de personas, actuar en consecuencia!
Anwar
3
@ Zeratops lol, esta respuesta tiene 6 años, era bastante verde cuando la escribí. Limpié la redacción para ser más al grano.
DForck42
9
  • Definición Básica

TEXTy VarChar(MAX)son tipos de datos de caracteres de longitud variable grande no Unicode, que pueden almacenar un máximo de 2147483647 caracteres no Unicode (es decir, la capacidad máxima de almacenamiento es: 2 GB).

  • ¿Cuál usar?

Según el enlace de MSDN, Microsoft sugiere evitar el uso del tipo de datos Texto y se eliminará en futuras versiones de SQL Server. Varchar (Max) es el tipo de datos sugerido para almacenar los valores de cadena grandes en lugar del tipo de datos Text.

  • Almacenamiento en fila o fuera de fila

Los datos de una Textcolumna de tipo se almacenan fuera de la fila en páginas de datos de LOB separadas. La fila en la página de datos de la tabla solo tendrá un puntero de 16 bytes a la página de datos de LOB donde están presentes los datos reales. Mientras que los datos de una Varchar(max)columna de tipo se almacenan en fila si es menor o igual a 8000 bytes. Si el valor de la columna Varchar (máx.) Cruza los 8000 bytes, el valor de la columna Varchar (máx.) Se almacena en páginas de datos LOB separadas y la fila solo tendrá un puntero de 16 bytes a la página de datos LOB donde están presentes los datos reales. Entonces, In-RowVarchar (Max) es bueno para búsquedas y recuperación.

  • Funcionalidades compatibles / no compatibles

Algunas de las funciones de cadena, operadores o construcciones que no funcionan en la columna Tipo de texto, pero sí funcionan en la columna de tipo VarChar (Max).

  1. = Igual al operador en la columna de tipo VarChar (Max)
  2. Agrupar por cláusula en la columna de tipo VarChar (Max)

    • Consideraciones de E / S del sistema

Como sabemos, los valores de la columna de tipo VarChar (Max) se almacenan fuera de la fila solo si la longitud del valor que se almacenará es mayor que 8000 bytes o si no hay suficiente espacio en la fila, de lo contrario, se almacenará en fila. Entonces, si la mayoría de los valores almacenados en la columna VarChar (Max) son grandes y se almacenan fuera de la fila, el comportamiento de recuperación de datos será casi similar al de la columna Tipo de texto.

Pero si la mayoría de los valores almacenados en columnas de tipo VarChar (Max) son lo suficientemente pequeños como para almacenar en fila. Luego, la recuperación de los datos donde no se incluyen las columnas LOB requiere la mayor cantidad de páginas de datos para leer, ya que el valor de la columna LOB se almacena en fila en la misma página de datos donde se almacenan los valores de las columnas no LOB. Pero si la consulta de selección incluye la columna LOB, entonces requiere menos cantidad de páginas para leer para la recuperación de datos en comparación con las columnas de tipo Texto.

Conclusión

Utilice VarChar(MAX)el tipo de datos en lugar de TEXTun buen rendimiento.

Fuente

Somnath Muluk
fuente
5

Si usa MS Access (especialmente versiones anteriores como 2003), se ve obligado a usar el TEXTtipo de datos en SQL Server ya que MS Access no reconoce nvarchar(MAX)como un campo Memo en Access, mientras que TEXTse reconoce como un campo Memo.

Klaus Oberdalhoff
fuente