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

use*_*116 186 sql-server performance varchar text sql-types

我刚刚读到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')

Rob*_*Day 305

VARCHAR(MAX)类型是替代品TEXT.基本区别在于TEXT类型将始终将数据存储在blob中,而VARCHAR(MAX)类型将尝试直接将数据存储在行中,除非它超过8k限制,并且此时它将数据存储在blob中.

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

关于您是否应该使用LIKE搜索,或者您应该使用全文索引CONTAINS.这个问题是无论相同VARCHAR(MAX)TEXT.

如果您正在搜索大量文本并且性能很关键,那么您应该使用全文索引.

LIKE 实现起来比较简单,通常适用于少量数据,但由于无法使用索引,因此大数据性能极差.

  • 我不知道它会在8k的页面中存储,如果更大则会在页面外存储.很酷. (11认同)
  • 你的最后一行是错误的.如果通配符位于要搜索的字符串的开头,则LIKE不能仅使用索引. (3认同)

Joe*_*orn 17

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


DFo*_*k42 15

如果不将文本字段从文本转换为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'
Run Code Online (Sandbox Code Playgroud)

这给出了一个错误:

The data types text and varchar are incompatible in the equal to operator.
Run Code Online (Sandbox Code Playgroud)

这不是:

declare @table table (a varchar(max))
Run Code Online (Sandbox Code Playgroud)

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

where a like '%a%'
Run Code Online (Sandbox Code Playgroud)

  • +1只是为了说随机downvote!当人们贬低我并且没有评论时,他会让我发疯,他们真的需要获得生命. (9认同)
  • 他投票的原因是**从我记忆中得到的**我不得不做的事情**在回答技术问题时不是一个有效的论据.想想人们(就像我现在一样)试图解释为什么我们应该使用`varchar(n)`或`text`,并克服这个答案.您是否认为,在专业环境中,用模糊陈述进行辩论将有助于解决问题?StackOverflow上的所有帖子都可以被成千上万的人看到,从而产生后果! (3认同)
  • @Zeratops大声笑,这个答案已经6岁了,当我写这篇文章的时候我很绿.我清理了措辞更加重要. (2认同)

Som*_*luk 9

  • 基本定义

TEXT并且VarChar(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数据页中,并且行只有一个16字节指针指向存在实际数据的LOB数据页.因此In-RowVarchar(Max)适用于搜索和检索.

  • 支持/不支持的功能

一些字符串函数,运算符或构造在Text类型列上不起作用,但它们适用于VarChar(Max)类型列.

  1. = 与VarChar(Max)类型列上的运算符相等
  2. VarChar(Max)类型列的分组依据

    • 系统IO注意事项

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

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

结论

使用VarChar(MAX)数据类型而不是TEXT良好的性能.

资源


小智 5

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