varchar(max)无处不在?

Bow*_*opa 80 varchar sql-server-2008

使所有Sql Server 2008字符串列varchar(max)有问题吗?我允许的字符串大小由应用程序管理.数据库应该坚持我给它的东西.通过在Sql Server 2008中将所有字符串列声明为varchar(max)类型,无论实际进入它们的数据大小如何,我都会受到性能影响吗?

Jus*_*tin 48

通过使用VARCHAR(MAX)你基本上告诉SQL Server"在这个字段中存储你最好看的值",然后SQL Server将选择是将值存储为常规VARCHAR还是存储为LOB(大对象).通常,如果存储的值小于8,000字节,SQL Server会将值视为常规VARCHAR类型.

如果存储的值过大,则列被获准在LOB页洒掉的页面,正是因为他们对其他LOB类型做(text,ntextimage) -如果发生这种情况,然后附加页读取需要读取存储在数据附加页面(即有性能),但只有在存储的值太大时才会出现这种情况.

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

简短版本:从存储的角度来看VARCHAR(MAX),VARCHAR(N)对于某些用户来说没有任何缺点N.

(注意,这也适用于其他可变长度字段类型NVARCHARVARBINARY)

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


gbn*_*gbn 33

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

这是一个缺点:因为它给出了

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

  • 我不知道我的数据是否总是<900.这是一个商业逻辑问题.如果该规则发生变化,我应该在业务逻辑中进行更改.我不应该也改变数据库.无论如何,那是我的目标.看看我是否能够远离数据库而不关注字符串大小而不会引起明显的性能损失. (8认同)
  • 创建索引时会收到警告,当您尝试插入> 900时会出现错误.但如果您的数据始终<900,为什么不使用900?是的,它们存储为可变长度的字符串. (3认同)
  • 索引长文本列多久有用一次?甚至值得为诸如varchar(200)列之类的索引编制索引吗?毕竟,索引本身效率很低。似乎不太可能需要搜索长时间的“完全匹配”。而且只有在已知模式开始的情况下,模式搜索才会受益。 (2认同)

Rob*_*ley 9

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

编辑:西蒙有一些关于varchar(max)的帖子.以下评论中的链接显示了这一点.我认为最重要的是http://sqlblogcasts.com/blogs/simons/archive/2009/07/11/String-concatenation-with-max-types-stops-plan-caching.aspx,其中讨论了效果varchar(max)对计划缓存的影响.一般原则是要小心.如果你不需要它是max,那么不要使用max - 如果你需要超过8000个字符,那么确定...去吧.


Mar*_*ith 6

对于这个问题,我没有看到提到的几点.

  1. 在2005/2008/2008 R2上,如果索引中包含LOB列,则会阻止联机索引重建.
  2. 2012年,在线索引重建限制被取消,但LOB列无法参与新功能添加NOT NULL列作为在线操作.
  3. 锁定可以在包含此数据类型的列的行上取出更长时间.(更多)

一对夫妇的其他原因都覆盖在我的答案,为什么不varchar(8000)到处.

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


Ata*_*oss 5

我之前也问过类似的问题。得到了一些有趣的回复。看看这里 在一个站点上,有一个人在谈论使用宽列的危害,但是,如果您的数据在应用程序中受到限制,那么我的测试将证明这一点。您无法在列上创建索引的事实意味着我不会一直使用它们(就我个人而言,我根本不会使用它们太多,但是在这方面我有点纯粹主义者)。但是,如果您知道其中没有太多存储,我认为它们没有那么糟糕。如果对其中具有varchar(max)的记录集的列进行任何排序(或者任何宽列为char或varchar),那么可能会遭受性能损失。这些可以通过索引来解决(如果需要),但是不能将索引放在varchar(max)上。如果您想将来验证您的色谱柱,为什么不将它们放在合理的位置。例如,名称列为255个字符,而不是最多...