【问题标题】:Are there disadvantages to using VARCHAR(MAX) in a table?在表中使用 VARCHAR(MAX) 有缺点吗?
【发布时间】:2011-02-04 02:01:58
【问题描述】:

这是我的困境。

基本上,我需要表格中的一列来容纳未知长度的字符。但我很好奇在 Sql Server 中使用列中的 VARCHAR(MAX) 或 NVARCHAR(MAX) 是否会出现性能问题,例如:“这次”我只需要存储 3 个字符,而且大多数时候我只需要存储 10 个字符。但是有一个很小的机会,它可能会在该列中达到几千个字符,甚至可能是一百万个,这是不可预测的。但是,我可以保证它不会超过 2GB 的限制。

我只是好奇是否存在任何性能问题,或者在可用的情况下解决此问题的更好方法。

【问题讨论】:

    标签: sql-server varchar nvarchar


    【解决方案1】:

    Crystal Reports 12(以及据我所知的其他版本)无法正确处理 varchar(max) 并将其解释为 varchar(255),从而导致报告中的数据被截断。

    因此,如果您使用的是 Crystal Reports,这对 varchar(max) 是不利的。准确地说,还是使用 Crystal 的缺点。

    见:
    http://www.crystalreportsbook.com/Forum/forum_posts.asp?TID=5843&PID=17503
    http://michaeltbeeitprof.blogspot.com/2010/05/crystal-xi-and-varcharmax-aka-memo.html

    【讨论】:

      【解决方案2】:

      我看到了一些问题——尤其是标量函数(但无论如何这些通常都很可怕),它们返回 varchar(MAX) 然后不重新转换。例如,假设您有一个特殊函数 CleanString(somevarcharmax) 返回 varchar(max) 并在 varchar(50) 上调用它,但不要 CAST(CleanString(varchar10col) AS varchar(10)) - 讨厌的性能问题。

      但通常,当您在表中有 varchar(max) 列时,您不应该大量执行这些类型的操作,所以我会说如果您正确使用它来满足表中的数据需求,然后就好了。

      【讨论】:

        【解决方案3】:

        您不能在 varchar(max)(和 nvarchar(max))列上创建索引(尽管它们可以包含在其中。但是谁会在索引中包含可能达到 2GB 的列?!)所以如果您想搜索在这个值上,除非你使用全文索引,否则每次都会进行扫描。此外,请记住,任何报表设计者或演示设计者(网络或其他)都必须假设有人可能会将百科全书放入该列并围绕它进行设计。没有什么比听到“用户可能不会做 X”更糟糕的了。如果用户可以做到,他们就会做到。如果用户可以将一本书放入一列中,那么他们会在某个时候这样做。如果他们永远不应该,那么 IMO,将列大小限制在某个合理的水平更有意义,如果用户试图在允许的列中填充更多内容,则会引发关于他们是否应该将该值输入的讨论第一列。

        【讨论】:

        • 我强烈反对。根据我的经验,用户经常遇到任意大小限制。 OTOH,我从未见过有人抱怨有人将整本百科全书复制到表格中。
        • @dan04 - IME,开发人员通常不会花时间了解列的实际意图。设置无限制的问题是用户将垃圾放入列中,因为他们可以然后抱怨当他们的报告被fubar'ed或屏幕加载缓慢或他们将FirstName LastName放入单个字段并且现在他们无法按最后排序名称等,因此您需要停止正在做的事情并修复他们的数据。没有任何限制,没有任何东西可以表明,直到为时已晚,有人试图将某些内容塞入不应存在的列中。
        • 问题是有些人实际上有 40 个字母的多连字符姓氏,当您尝试将其强制转换为 VARCHAR(16) 时会抱怨。
        • @dan04 - 我们同意的一件事是:我讨厌任意的大小限制。这里的关键词是任意。这意味着开发人员从未就给定列的最正确大小咨询客户或任何其他来源。因此,虽然我们同意姓氏的 varchar(16) 太小,但我也认为姓氏的 varchar(max) 是同样愚蠢的。
        【解决方案4】:

        前几天我刚看到this 的文章。它记录了 varchar(max) 相对于 varchar(n) 列的相当小的性能滞后。可能不足以为您带来改变。但如果是这样,也许您可​​以使用单独的表来存储这几个大文本块。您的小文本可以保留在主表格中,但您可以添加一个标志字段来告诉您在新表格中查找大文本。

        【讨论】:

          【解决方案5】:

          不,varchar(max) 会根据条目的大小自行调整,因此如果您要使用各种大小的输入,它是最有效的。

          【讨论】:

          • varchar(max),不管放多少信息,实际上分配 n btyte 长度 + 2 个字节,但实际的惩罚是它不允许列索引,即使只消耗一字节数据。为了掩盖缺乏数据结构规划,这太低效了。
          【解决方案6】:

          在我看来,您打算将 varchar(MAX) 数据类型用于其预期目的。

          当 MAX 数据类型中的数据超过 8 KB 时,将使用溢出页面。 SQL Server 2005 自动为页面分配一个溢出指示符,并且知道如何像处理其他数据类型一样处理数据行。

          如需进一步阅读,请查看在线图书:char and varchar

          【讨论】:

          • 虽然完全正确,但我会避免使用术语溢出,因为 Row-Overflow 是 varchar(n) 的页面类型名称,而 varchar(max) 转到“Lob Data”页面使用 DBCC Ind 查看时键入。
          • 那么“是否存在任何性能问题”问题的答案?是不是 - 当它溢出时可能只是微不足道的一点?这是正确的吗?
          猜你喜欢
          • 2010-09-13
          • 2010-10-03
          • 2011-09-15
          • 1970-01-01
          • 2012-03-21
          • 1970-01-01
          • 2011-02-11
          • 2010-12-12
          相关资源
          最近更新 更多