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

时间:2009-05-07 13:56:35

标签: sql-server performance text varchar sql-types

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

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

  1. LIKE列使用VARCHAR(MAX)子句?

    WHERE COL1 LIKE '%search string%'

  2. 使用TEXT列并在此列上放置全文索引 / 目录,然后使用CONTAINS进行搜索条款?

    WHERE CONTAINS (Col1, 'MyToken')

5 个答案:

答案 0 :(得分:295)

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

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

关于是否应使用LIKE进行搜索,或者是否应使用全文索引CONTAINS。无论VARCHAR(MAX)TEXT是什么,此问题都是相同的。

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

LIKE更容易实现,并且通常适用于少量数据,但由于无法使用索引,因此大数据的性能极差。

答案 1 :(得分:17)

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

答案 2 :(得分: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'

这会出错:

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

这不是:

declare @table table (a varchar(max))

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

where a like '%a%'

答案 3 :(得分:8)

  • 基本定义

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

  • 使用哪一个?

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

  • 行内或行外存储

Text类型列的数据存储在单独的LOB数据页中的行外。表数据页中的行只有一个16字节指针指向存在实际数据的LOB数据页。而Varchar(max)类型列的数据如果小于或等于8000字节则存储在行内。如果Varchar(max)列值超过8000字节,则Varchar(max)列值存储在单独的LOB数据页中,并且行只有一个16字节指针指向存在实际数据的LOB数据页。所以In-Row Varchar(Max)适合搜索和检索。

  • 支持/不支持的功能

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

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

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

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

    <强>结论

    使用VarChar(MAX)数据类型而非TEXT以获得良好的效果。

    Source

答案 4 :(得分:4)

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