SQL性能:使用NVarchar(MAX)而不是NVarChar(200)是否会有性能损失?

46

请问定义nvarchar(max)列类型是否存在不利之处,相比于给它一个(更小的)最大大小?

我在某个地方读到,如果列值超过4KB,则剩余数据将被添加到“溢出”区域中,这没问题。

我正在创建一张表,其中大部分时间文本只有几行,但我想知道是否在设置较低的限制后添加验证以避免超出限制时是否有任何优势。

是否有关于使用nvarchar(max)列创建索引的限制?或者为了增加大小限制而付出的任何代价?

谢谢!

3个回答

51

严格来说,MAX类型总体上比非-MAX类型略慢,参见varchar(max) vs. varchar(N)的性能比较。但在实践中,这种差异是不可见的,因为它只会成为IO驱动的整体性能中的噪声。

您的主要关注点不应该是MAX与非MAX的性能问题。您应该关心的问题是,“这个列可能需要存储超过8000个字节吗?”即使答案是“可能”,即使这是一个非常不可能的“可能”,那么答案也很明显:使用MAX类型,将来将此列转换为MAX类型的痛苦不值得非-MAX类型略微提高的性能。

其他问题(例如是否可以对该列进行索引,在具有MAX列的表上无法进行在线索引操作)已经由Denis的回答解决了。

顺便说一句,有关超过4KB的列仍有剩余数据的信息是错误的。正确的信息在表和索引组织中:

ROW_OVERFLOW_DATA分配单元

对于表(堆或聚集表)、索引或索引视图使用的每个分区,都有一个ROW_OVERFLOW_DATA分配单元。此分配单元包含零(0)页,直到具有可变长度列(varchar、nvarchar、varbinary或sql_variant)的数据行在IN_ROW_DATA分配单元中超过8 KB的行大小限制。当达到大小限制时,SQL Server将具有最大宽度的列从该行移动到ROW_OVERFLOW_DATA分配单元中的一个页面中。原始页面上维护指向此离散行数据的24字节指针。

因此,问题不在于超过4KB的列,而是行无法适应页面上的可用空间,而且问题不在于“剩余空间”,而是整个列。

SQL 2012:您无法在分区级别上执行在线索引重建。但是,您可以对除文本、ntext、image之外的所有数据类型的整个索引执行在线索引重建。这意味着具有varchar(max)、nvarchar(max)和varbinary(max)列的表可以在SQL 2012中进行在线重建。SQL 2014:您可以在分区级别上执行在线索引重建。您可以对varchar(max)、nvarchar(max)和varbinary(max)数据类型执行在线索引重建。与SQL 2012一样,不包括文本、ntext、image。这些是遗留数据类型,随着时间的推移应该逐渐淘汰。 - Triynko
然而,我从一位同事那里听说过一个表格正在使用nvarchar(max)字段连接另一个表格,并通过将其更改为nvarchar(100)获得了30%的时间减少。滥用nvarchar(max)也不是理想的选择。 - Caveman

21

一个超过900字节的列上无法创建索引。大型对象(LOB)数据类型ntext、text、varchar(max)、nvarchar(max)、varbinary(max)、xml或image的列不能作为索引的关键列。

但是,您可以使用包含的列

除了text、ntext和image之外,所有数据类型都允许使用。如果指定的非关键列中有任何一个是varchar(max)、nvarchar(max)或varbinary(max)数据类型,则必须离线创建或重建索引(ONLINE = OFF)。


太好了!这就是我在寻找的那种信息。谢谢。 - willvv
1
+1. 在线操作的不可用性实际上是一个重要的因素: 引入 MAX 列会使所有的在线操作不可用。 - Remus Rusanu
1
在线操作是什么意思? - NickG
重建索引有两种方式:离线和在线。离线重建时,数据在重建期间不可用;在线重建时,数据是可用的(除了创建索引时持有锁的短暂时间)。 - SQLMenace
2
请注意,在SQL Server 2012+中,必须为varchar(max)构建离线的限制已经消失。链接 - Gabe
SQL 2012:您无法在分区级别上执行在线索引重建。但是,您可以对除文本、ntext、image之外的所有数据类型的整个索引执行在线索引重建。这意味着具有varchar(max)、nvarchar(max)和varbinary(max)列的表可以在SQL 2012中在线重建。SQL 2014:您可以在分区级别上执行在线索引重建。您可以对varchar(max)、nvarchar(max)和varbinary(max)数据类型执行在线索引重建。与SQL 2012一样,不包括文本、ntext、image。这些是遗留数据类型,随着时间的推移应该逐渐淘汰。 - Triynko

5
选择nvarchar(max)也会影响由SQL Server引擎自动适应的执行计划优化。

3
如果“affect”是积极的或消极的,可能值得加上说明,并且可能需要提供一个相关链接作为参考。 - TravisWhidden
我在这里找到了它 https://dev59.com/pWkw5IYBdhLWcg3wUI1W#45806109 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接