Sql server SQL性能:使用NVarchar(最大值)而不是NVarchar(200)是否会影响性能

Sql server SQL性能:使用NVarchar(最大值)而不是NVarchar(200)是否会影响性能,sql-server,performance,indexing,nvarchar,Sql Server,Performance,Indexing,Nvarchar,我想知道定义nvarchar(max)类型的列而不是给它一个(较小的)最大大小是否有任何缺点 我在某个地方读到,如果列值超过4KB,剩余的数据将被添加到“溢出”区域,这是可以的 我正在创建一个表,其中大部分时间文本都只有几行,但我想知道设置一个下限,然后添加一个验证以避免打破该限制是否有好处 是否对使用nvarchar(max)列创建索引有任何限制,或者对必须添加大小限制的内容有任何限制 谢谢 不能在超过900字节的列上创建索引。不能将大对象(LOB)数据类型ntext、text、varchar

我想知道定义nvarchar(max)类型的列而不是给它一个(较小的)最大大小是否有任何缺点

我在某个地方读到,如果列值超过4KB,剩余的数据将被添加到“溢出”区域,这是可以的

我正在创建一个表,其中大部分时间文本都只有几行,但我想知道设置一个下限,然后添加一个验证以避免打破该限制是否有好处

是否对使用nvarchar(max)列创建索引有任何限制,或者对必须添加大小限制的内容有任何限制


谢谢

不能在超过900字节的列上创建索引。不能将大对象(LOB)数据类型ntext、text、
varchar(max)
、nvarchar(max)、varbinary(max)、xml或image的列指定为索引的键列

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


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

严格来说,
max
类型总是比非max类型慢一点,请参阅。但这种差异在实践中是看不到的,它只是IO驱动的总体性能中的噪音

您主要关心的不应该是MAX与非MAX的性能。您应该关心的问题是,此列可能需要存储8000多个字节?如果答案是肯定的,即使是非常不可能是肯定的,那么答案是显而易见的:使用MAX类型,以后将此列转换为MAX类型所带来的痛苦与非MAX类型的微小性能优势相比是不值一提的

Denis的回答已经解决了其他问题(对该列进行索引的可能性、对具有最大列的表进行在线索引操作的不可用性)

顺便说一句,关于超过4KB的列在溢出区域中有剩余数据的信息是错误的。以下是正确的信息:

行溢出数据分配单元

对于表使用的每个分区 (堆或聚集表)、索引或 索引视图,有一个 行溢出数据分配单元。 此分配单元包含零(0) 页面直到包含变量的数据行 长度列(varchar、nvarchar、, 在 在行数据分配单元超过 8 KB的行大小限制。当尺寸 已达到限制,SQL Server 移动具有最大值的列 从该行到中某页的宽度 行溢出数据分配单元。A. 指向该行外数据的24字节指针 在原始页面上维护


因此,不是超过4KB的列,不是不适合页面上可用空间的行,也不是“剩余”,而是整个列。

选择nvarchar(max)也会影响sql server引擎自动调整的执行计划优化。

太好了!这就是我一直在寻找的信息。谢谢你。联机操作不可用实际上是一个重要问题:引入MAX列会使所有联机操作不可用。联机操作是什么意思?脱机和联机重建索引有两种方法,脱机重建时,数据将在重建期间不可用,联机时,数据可用(除了创建索引时的一小段时间,锁定被保留)请注意,必须为varchar(max)脱机生成的这种限制在SQL Server 2012+中已经消失。如果“影响”是好的还是坏的,可能值得添加,并且可能是一个显示引用的链接。我在这里找到了“SQL 2012:您不能在分区级别进行联机索引重建。但是,您可以对除text、ntext、image之外的所有数据类型的整个索引进行联机索引重建。这意味着使用varchar(max)、nvarchar(max)的表,和varbinary(max)列可以在SQL 2012中联机重建。SQL 2014:您可以在分区级别执行联机索引重建。您可以执行varchar(max)、nvarchar(max)和varbinary(max)的联机索引重建数据类型。与SQL 2012一样,不包括文本、ntext和图像。这些是遗留数据类型,确实应该随着时间的推移逐步淘汰。”