84

将所有 Sql Server 2008 字符串列设为 varchar(max) 是否有任何问题?我允许的字符串大小由应用程序管理。数据库应该只保留我给它的东西。在 Sql Server 2008 中将所有字符串列声明为 varchar(max) 类型是否会影响性能,无论实际进入它们的数据大小如何?

4

7 回答 7

50

通过使用VARCHAR(MAX),您基本上是在告诉 SQL Server“将值存储在此字段中的最佳方式”,然后 SQL Server 将选择将值存储为常规值VARCHAR还是 LOB(大对象)。通常,如果存储的值小于 8,000 字节,SQL Server 会将值视为常规VARCHAR类型。

如果存储的值太大,则允许该列从页面溢出到 LOB 页面,就像它们对其他 LOB 类型(textntext)所做的那样image- 如果发生这种情况,则需要额外的页面读取来读取存储在中的数据额外的页面(即有一个性能),但是只有在存储的值太大时才会发生这种情况

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

短版:VARCHAR(MAX)从存储的角度来看,使用over VARCHAR(N)for some没有任何缺点N

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

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

于 2011-07-27T16:15:16.433 回答
37

一个索引的宽度不能超过 900 字节。因此,您可能永远无法创建索引。如果您的数据小于 900 字节,请使用 varchar(900)。

这是一个缺点:因为它给

  • 搜索性能真的很差
  • 没有唯一的约束
于 2010-01-19T06:01:24.183 回答
10

西蒙萨宾不久前写了一篇关于这个的帖子。我现在没有时间去抓它,但你应该搜索它,因为他得出的结论是你不应该默认使用 varchar(max) 。

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

于 2010-01-19T05:27:40.703 回答
6

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

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

我的回答中涵盖了其他几个原因,为什么不是varchar(8000)无处不在

  1. 您的查询最终可能会请求大量的内存授予,而数据大小并不合理。
  2. 在带有触发器的表上,它可以防止未添加版本控制标签的优化。
于 2012-12-27T20:14:15.270 回答
5

I asked the similar question earlier. got some interesting replies. check it out here There was one site that had a guy talking about the detriment of using wide columns, however if your data is limited in the application, my testing disproved it. The fact you can't create indexes on the columns means I wouldn't use them all the time (personally i wouldn't use them that much at all, but i'm a bit of a purist in that regard). However if you know there isn't much stored in them, i don't think they are that bad. If you do any sorting on columns a recordset with a varchar(max) in it (or any wide column being char or varchar), then you could suffer performance penalties. these could be resolved (if required) by indexes, but you can't put indexes on varchar(max). If you want to future proof your columns, why not just put them to something reasonable. eg a name column be 255 characters instead of max... that kinda thing.

于 2011-08-22T21:49:39.717 回答
2

避免在所有列上使用 varchar(max) 还有另一个原因。出于同样的原因,我们使用检查约束(以避免使用错误软件或用户条目导致的垃圾填充表),我们希望防止任何添加比预期更多数据的错误进程。例如,如果某人或某物试图将 3,000 字节添加到 City 字段中,我们将确定有问题,并希望停止进程死在其轨道上,以便尽早对其进行调试。我们还会知道 3000 字节的城市名称不可能是有效的,并且如果我们尝试使用它会弄乱报告等。

于 2016-04-27T18:09:08.987 回答
1

理想情况下,您应该只允许您需要的东西。这意味着如果您确定特定列(例如用户名列)的长度永远不会超过 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 字节吗?

于 2010-01-19T06:00:38.877 回答