我有一个声明为nvarchar(4000)的列,而4000是SQL Server对nvarchar长度的限制。它不会被用作排序行的键。
在将nvarchar字段的长度设置为4000之前,我是否应该注意哪些含义?
更新
我确实存储了一个XML,一个XML序列化对象。我知道这不是有利的,但我们很可能永远不需要对它进行查询,这种实现大大减少了我们计划扩展的某些功能的开发时间。我希望XML数据平均长度为1500个字符,但可能存在长度超过4000的例外情况。它可能超过4000个字符吗?它可能是在非常罕见的情况下,如果它发生的话。这个应用程序任务是否关键不,完全没有。
答案 0 :(得分:4)
SQL Server有三种类型的存储:行内,LOB和行溢出,请参阅Table and Index Organization。行内存储访问速度最快。 LOB和Row-Overflow彼此相似,都比行内稍慢。
如果您有一列NVARCHAR(4000),它将尽可能存储在行中,否则它将存储在行溢出存储中。拥有这样一个列并不一定表明未来的性能问题,但它引出了一个问题:为什么nvarchar(4000)?您的数据可能总是接近4000个字符吗?它可以是4001,在这种情况下你的应用程序将如何处理它?为什么不nvarchar(max)?你有没有测量过性能,发现nvarchar(max)对你来说太慢了?
我的建议是使用较小的nvarchar长度,适用于真实数据,或者nvarchar(max)如果预计会很大。 nvarchar(4000)闻起来像是不合理的,没有经过过早优化测试。
<强>更新强>
对于XML,请使用XML data type。它比varchar或nvarchar有许多优点,比如它支持XML indexes,它支持XML methods,并且实际上可以验证XML是否符合特定模式,或者至少是格式良好的XML遵从性
XML将存储在行外的LOB存储中。
即使数据不是XML,我仍然会推荐长度为1500的LOB存储(nvarchar(max))。检索LOB存储数据会产生相关成本,但成本不仅仅是补偿的通过macking表 narrower 。表行的宽度是性能的主要因素,因为更宽的表每页的行数更少,因此任何必须扫描一系列行或整个表的操作都需要将更多页面提取到内存中,这显示在查询成本(实际上是 总成本的驱动因素)。 LOB存储列只扩展行的大小,其宽度为“页面id”,如果我没记错的话,这是8个字节,这样你就可以获得更好的每页行密度,从而加快查询速度。
答案 1 :(得分:3)
你确定你真的需要多达4000个字符吗?如果1000是实际上限,为什么不将其设置为?相反,如果您可能获得超过4000个字节,则需要查看nvarchar(max)。
我喜欢“鼓励”用户不要太自由地使用存储空间。存储给定行所需的空间越多,每页可存储的空间就越少,这可能会在读取或写入表时导致更多的磁盘I / O.尽管只需要存储尽可能多的字节数据(即不是每行完整的4000个),但每当你获得超过2000个字符的nvarchar数据时,每页只有一行,而且性能真的可以受到影响。
这当然假设您需要存储unicode(双字节)数据,并且每行只有一个这样的列。如果不这样做,请下拉到varchar。
答案 2 :(得分:2)
你当然需要nvarchar,还是可以使用varchar?该限制主要适用于sql server 2k。你使用的是2k5 / 2k8吗?