在SQL Server上使用varchar(MAX)vs TEXT


195

我刚刚读到,该VARCHAR(MAX)数据类型(可以存储将近2GB的char数据)是TEXTSQL Server 2005和Next SQL SERVER版本中推荐的数据类型的替代。

如果我想在列内搜索任何字符串,哪个操作更快?

  1. LIKEVARCHAR(MAX)列使用子句?

    WHERE COL1 LIKE '%search string%'

  2. 使用该TEXT列并将全文索引 / 目录放在此列上,然后使用该CONTAINS子句进行搜索?

    WHERE CONTAINS (Col1, 'MyToken')


1
这篇文章也很有帮助:stackoverflow.com/questions/564755/…– 2010
杰克

24
该帖子中最重要的提及是指向MSDN文档的链接,该链接显示TEXTNTEXT(和IMAGE)已弃用。
布莱恩(Brian)

Answers:


315

VARCHAR(MAX)类型是的替代TEXT。基本区别在于,TEXT类型将始终将数据存储在blob中,而该VARCHAR(MAX)类型将尝试将数据直接存储在行中,除非它超过8k限制,然后将其存储在blob中。

在两种数据类型之间使用LIKE语句是相同的。附加的功能VARCHAR(MAX)给你的是,它也可以被用来=GROUP BY其他任何VARCHAR列都可以。但是,如果您确实有很多数据,那么使用这些方法会遇到巨大的性能问题。

关于是否应该使用LIKE搜索,或者是否应该使用全文索引CONTAINS。不论VARCHAR(MAX)还是,这个问题都是一样的TEXT

如果要搜索大量文本,而性能是关键,则应使用全文索引

LIKE 它易于实现,并且通常适用于少量数据,但是由于无法使用索引,因此在处理大数据时性能极差。


12
我不知道它将以8k的大小存储在页面中,如果更大则将存储在页面之外。很酷。
Brain2000

3
您的最后一行是部分错误的。如果通配符位于要搜索的字符串的开头,则LIKE只能使用索引。
SouravA 2015年

1
从具有数据的现有表中将文本字段更改为varchar(max)没问题吗?
user1531040 '17

17

对于大的文本时,全文索引快。但是您也可以全文索引 varchar(max)


16

如果不将文本字段从文本转换为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'

这给出了一个错误:

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

Wheras这不会:

declare @table table (a varchar(max))

有趣的是,LIKE仍然有效,即

where a like '%a%'

11
+1只是说随机下注!当人们对我投反对票而无可奉告时,他们会让我发疯,他们确实需要谋生。
汤姆·斯蒂克

3
他之所以不赞成投票,是因为我记得我必须做的事情并不是回答技术问题时要提出的有效论据。考虑一下人们(现在就像我一样)试图弄清楚为什么要使用varchar(n)text,并克服这个答案。您是否认为,在职业环境中,以模糊的说法争论将有助于解决问题?StackOverflow上的所有帖子都应被成千上万的人看到,以后果自负!
Anwar

3
@Zeratops大声笑,这个答案是6岁了,我写这本书的时候还是很环保的。我整理了措辞,使内容更切合实际。
DForck42,2015年

9
  • 基本定义

TEXTVarChar(MAX)是非Unicode大可变长度字符数据类型,它可以存储最大的2147483647非Unicode字符(即最大存储容量是:2GB)。

  • 使用哪一个?

根据MSDN链接, Microsoft建议避免使用Text数据类型,它将在Sql Server的将来版本中将其删除。Varchar(Max)是用于存储大字符串值的建议数据类型,而不是Text数据类型。

  • 行内或行外存储

Text类型列的数据行外存储在单独的LOB数据页中。表数据页中的行将只有16个字节的指针指向实际数据所在的LOB数据页。Varchar(max)如果类型列的数据小于或等于8000个字节,则将其存储在行中。如果Varchar(max)列的值超过了8000个字节,则Varchar(max)列的值将存储在单独的LOB数据页中,并且行将仅具有指向存在实际数据的LOB数据页的16字节指针。因此,In-RowVarchar(Max)非常适合搜索和检索。

  • 支持/不支持的功能

某些字符串函数,运算符或构造在Text type列上不起作用,但在VarChar(Max)type列上起作用。

  1. = 等于VarChar(Max)类型列上的运算符
  2. 在VarChar(Max)类型列上按子句分组

    • 系统IO注意事项

我们知道,仅当要存储在其中的值的长度大于8000个字节或行中没有足够的空间时,才会在行外存储VarChar(Max)类型的列值,否则它将存储它在行中。因此,如果存储在VarChar(Max)列中的大多数值很大并且存储在行外,则数据检索行为将几乎类似于“文本类型”列的行为。

但是,如果大多数存储在VarChar(Max)类型列中的值都足够小,可以存储行内。然后,要检索不包含LOB列的数据,需要读取更多数量的数据页,因为将LOB列值行存储在存储非LOB列值的同一数据页中。但是,如果选择查询包含LOB列,则与Text类型列相比,它需要较少的页面数来读取数据。

结论

使用VarChar(MAX)数据类型而不是TEXT为了获得良好的性能。

资源


5

如果使用MS Access(尤其是像2003这样的旧版本),则您将被迫TEXT在SQL Server上使用数据类型,因为MS Access在Access中不被识别nvarchar(MAX)为备注字段,而在备注字段中TEXT被识别。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.