我想知道在定义nvarchar(max)类型的列时是否有任何缺点,而不是给它一个(更小的)最大大小。
我在某处读到,如果列值超过4?KB,剩余数据将被添加到“溢出”区域,这没关系。
我正在创建一个表,其中大部分时间文本都是几行,但我想知道设置下限然后添加验证是否有任何优势以避免违反该限制。
使用nvarchar(max)列创建索引是否有任何限制,或者是否需要在大小限制上添加限制?
谢谢!
答案 0 :(得分:34)
严格来说,MAX
类型总是比非MAX类型慢一点,请参阅Performance comparison of varchar(max) vs. varchar(N)。但是这种差异在实践中永远不可见,它只会在由IO驱动的整体性能中产生噪音。
您的主要关注点不应该是MAX与非MAX的表现。您应该关注这个问题,这个列可能需要存储超过8000个字节吗?如果答案是肯定的,即使是非常不太可能,那么答案是显而易见:使用MAX类型,以后将此列转换为MAX类型的痛苦不值得非MAX类型的次要性能优势。
Denis的回答已经解决了其他问题(索引该列的可能性,具有MAX列的表的ONLINE索引操作不可用)。
BTW,有关溢出区域中剩余数据的4KB以上列的信息是错误的。正确的信息位于Table and Index Organization:ROW_OVERFLOW_DATA分配单元
对于表使用的每个分区 (堆或聚簇表),索引或 索引视图,有一个 ROW_OVERFLOW_DATA分配单位。 此分配单元包含零(0) 页面直到带有变量的数据行 长度列(varchar,nvarchar, varbinary,或sql_variant) IN_ROW_DATA分配单位超出 8 KB行大小限制。当大小 达到了限制,SQL Server 移动最大的列 从该行到页面中的页面的宽度 ROW_OVERFLOW_DATA分配单位。一个 指向此行外数据的24字节指针 保留在原始页面上。
因此,不是超过4KB的列,是不适合页面上可用空间的行,而不是“剩余”,是整个列。
答案 1 :(得分:17)
无法在超过900字节的列上创建索引。大对象(LOB)数据类型ntext,text,varchar(max)
,nvarchar(max),varbinary(max),xml或image的列不能指定为索引的键列
但您可以使用included columns
除text,ntext和image之外,允许使用所有数据类型。如果任何一个指定的非键列是varchar(max),nvarchar(max)或varbinary(max)数据类型,则必须脱机创建或重建索引(ONLINE = OFF)。
答案 2 :(得分:2)
选择nvarchar(max)也会影响sql server引擎自动调整的执行计划优化。