varchar(MAX)始终是首选吗?

87

关于 SQL Server,我理解:

  • var 意味着内存是延迟分配的,也就是说它与数据完全匹配(在插入时)。

  • MAX 意味着没有大小限制/限制。

那么,在使用 varchar 时,总是优先考虑使用 MAX 吗?毕竟我们无论如何都不会分配整个大小的空间吗?

如果对此数据库列有约束条件,我们应该只使用一个固定的大小吗?


5
这取决于数据库系统,你指的是哪个? - jjmontes
1
此外,我想补充一点,长度限制是数据模型约束的一部分,有些人在这个层面上也非常严格。 - jjmontes
13
另一个要点:由于 SQL Server 中的索引条目最多只能是 900 字节,因此您绝对不能在 VARCHAR(MAX) 列上创建索引......如果您需要索引,则这不是一个好事情! - marc_s
“如果我们想在数据库列上强制执行约束条件,那么我们应该仅使用常量大小吗?”——你让它听起来好像这样的列是两种可能性中较不常见的。我的经验告诉我相反。 - onedaywhen
答案是否定的,使用VARCHAR(MAX)并不理想。请参见下文以了解更多细节。 - Shanerk
请查看以下链接:https://dev59.com/I14b5IYBdhLWcg3wiSTV - vicky
4个回答

67

这个主题有一篇非常好的文章,作者是SO用户@Remus Rusanu。我摘录了一个片段,但建议您阅读整篇文章:

处理MAX类型(varchar、nvarchar和varbinary)的代码路径与处理它们等效的非max长度类型的代码路径不同。非max类型可以内部表示为普通的指针和长度结构。但是,由于max类型可能增长到2Gb,因此无法将它们作为连续的内存区域存储。所以它们必须通过流接口来表示,类似于COM的IStream。这也适用于涉及最大类型的每个操作,包括简单的赋值和比较,因为这些操作在流接口上更加复杂。影响最大的是分配和赋值最大类型变量的代码(我的第一个测试),但影响在每个操作中都可见。

在文章中,他展示了几个示例,证明使用varchar(n)通常可以提高性能。

您可以在这里找到整篇文章。


1
同时,MAX类型阻止在线操作,至少在SQL Server 11之前是如此。http://rusanu.com/2011/08/05/online-index-operations-for-indexes-containing-lob-columns/ - Remus Rusanu
3
那么,使用 varchar(n) 时,您可以使用的最大值为 n,以便仍然获得使用 varchar(n) 的好处是多少? - Superdooperhero
@Superdooperhero,最大的n是8000。 - aturc
"过早的优化是万恶之源。"--Donald Knuth - allyourcode

20

16

以下是微软的建议:

  • 当列数据项的大小一致时,请使用 char。
  • 当列数据项目的大小差异很大时,请使用 varchar。
  • 当列数据项的大小差异很大且可能超过 8,000 字节时,请使用 varchar(max)。

参考文献


4
我猜是因为声称可以在所有情况下使用VARCHAR(MAX)是错误的,对吗? - HardCode
1
你当前编辑的答案与你原始的答案差异巨大,无论你是否在原始答案中有意这样做。 - HardCode
1
第一个答案是错误的,所以我给它点了踩。你基本上暗示说可以随意使用varchar(max),而不会有任何后果。错误的答案应该(并且会)受到负评。 - JNK

14

明确指出,答案是否定的。使用varchar(N)始终是更可取的选择,如果您知道大小不会变化,则可以使用char(N)。MAX类型不支持大多数本地SQL功能,因此无法在这些类型上添加索引、执行连接或进行有效的搜索。顺便说一句,这就是SQL Server存在全文搜索功能的原因之一。

此外,varchar(max)会阻止对包含varchar(max)字段的整个表格执行在线索引。这将严重影响系统性能。

如果字段大小已知超过8K,则应只使用Varchar(max)。在其他情况下,必须指定大小。否则,这是设计不良并且肯定会导致任何除最简单系统外的性能问题。

一些参考:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接