varchar(max)到处?

是否有任何问题,使所有的SQL Server 2008string列varchar(max)。 我允许的string大小由应用程序pipe理。 数据库应该坚持我给它的东西。 在Sql Server 2008中,我将通过声明所有的string列types为varchar(max),而不pipe实际进入的数据的大小是否会使性能下降?

通过使用VARCHAR(MAX)您基本上告诉SQL Server“将值存储在这个字段中如何看最好”,然后SQL Server将select是将值存储为常规VARCHAR还是LOB(大对象)。 一般情况下,如果存储的值小于8,000字节,SQL Server会将值视为常规的VARCHARtypes。

如果存储的值太大,则允许列将页面溢出到LOB页面,正如对于其他LOBtypes( textntextimage )那样 – 如果发生这种情况,则需要额外的页面读取以读取存储在附加页面中的数据(也就是有一个性能低下),但是只有当存储的值太大时才会发生这种情况

事实上,在SQL Server 2008或更高版本中,即使使用固定长度的数据types(例如VARCHAR(3,000) ),数据也可能溢出到其他页面上,但是这些页面被称为行溢出数据页面,并且处理方式稍有不同。

简短版本:从存储angular度来看,对于某些N ,使用VARCHAR(MAX)优于VARCHAR(N)是没有缺点的。

(请注意,这也适用于其他可变长度字段typesNVARCHARVARBINARY

仅供参考 – 您无法在VARCHAR(MAX)列上创build索引

一个索引不能超过900个字节。 所以你可能永远不会创build一个索引。 如果您的数据less于900字节,请使用varchar(900)。

这是一个缺点:因为它给

  • 非常糟糕的search性能
  • 没有独特的限制

西蒙·萨宾在一段时间后写了一篇文章。 我现在没有时间去抓它,但是你应该search它,因为他得出的结论是你不应该使用默认的varchar(max)。

编辑:西蒙有几个关于varchar(max)的post。 下面的评论中的链接很好地显示了这一点。 我认为最重要的是http://sqlblogcasts.com/blogs/simons/archive/2009/07/11/String-concatenation-with-max-types-stops-plan-caching.aspx ,它谈论的效果在计划caching上的varchar(max)。 总的原则是要小心。 如果你不需要它是最大的,那么不要使用最大 – 如果你需要超过8000个字符,那么肯定…去吧。

对于这个问题,特别是我没有看到提到的几点。

  1. 在2005/2008/2008 R2中,如果索引中包含LOB列,将阻止在线索引重build。
  2. 在2012年,在线索引重build限制被解除,但LOB列无法参与新function。 将NOT NULL列添加为在线操作 。
  3. 在包含此数据types的列的行上可以取出更长的锁。 ( 更多 )

在我的答案中, 为什么不是varchar(8000)到处都有其他几个原因。

  1. 您的查询可能最终会要求大量的内存授权,而不是数据大小。
  2. 在带有触发器的表上,它可以防止未添加版本控制标签的优化。

我之前问过类似的问题。 有一些有趣的回复。 看看这里有一个网站有一个人谈论不利于使用宽列,但是,如果你的数据是有限的应用程序,我的testing反驳它。 你不能在列上创build索引的事实意味着我不会一直使用它们(我个人根本不会使用它们,但是在这方面我是一个纯粹主义者)。 但是,如果你知道存储的内容不多,我认为它们不是那么糟糕。 如果你在列上做了一个logging集,其中有一个varchar(max)(或任何宽的列是char或varchar),那么你可能会遭受性能损失。 这些可以通过索引来解决(如果需要的话),但是你不能把索引放在varchar(max)上。 如果你想为将来certificate你的专栏,为什么不把它们合理的。 例如一个名称列是255个字符,而不是最大…这种事情。

还有一个原因是避免在所有列上使用varchar(max)。 出于同样的原因,我们使用检查约束(为了避免由于错误的软件或用户条目导致垃圾填充表),我们希望防止任何错误的过程,比预期的添加更多的数据。 例如,如果某人或某事试图将3000字节添加到城市字段中,我们将确定知道某些事情是不正常的,并希望停止该过程,以便尽早debugging该过程。 我们也知道一个3000字节的城市名称不可能是有效的,如果我们试图使用它,会弄乱报告。

理想情况下,你应该只允许你需要的东西。 这意味着如果你确定一个特定的列(比如说一个用户名列)永远不会超过20个字符,那么使用VARCHAR(20)和VARCHAR(MAX)可以使数据库优化查询和数据结构。

从MSDN: http : //msdn.microsoft.com/en-us/library/ms176089.aspx

 Variable-length, non-Unicode character data. n can be a value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes. 

你真的会去这些列接近2 ^ 31-1字节?