varchar(500)比varchar(8000)更有优势吗?

xminus 发布于 2018-09-09 sql 最后更新 2018-09-09 23:22 1837 浏览

我在MSDN论坛上阅读过这篇文章,但我仍然不清楚。我认为这是正确的:Varchar(max)将被存储为文本数据类型,所以有缺陷。因此,让我们说你的领域将可靠地低于8000个字符。就像我的数据库表中的BusinessName字段一样。事实上,一个企业名称可能总是在500个字符之内(拉出一个数字而不是我的帽子)。我似乎有很多varchar字段在8K字符数下运行。 那么我应该使该字段为varchar(500)而不是varchar(8000)?根据我对SQL的理解,这两者之间没有区别。所以,为了简化生活,我想将所有的varchar字段定义为varchar(8000)。这有什么缺点吗? 相关:Size of varchar columns(我不觉得这个回答了我的问题)。

已邀请:

onon

赞同来自:

这可以产生影响的一个示例是它可以阻止性能优化,避免将行版本控制信息添加到具有after触发器的表。 This is covered by SQL Kiwi here

The actual size of the data stored is immaterial – it is the potential size that matters.
过度声明列宽可能产生很大差异的另一种情况是,是否使用SSIS处理表。为可变长度(非BLOB)列分配的内存对于执行树中的每一行是固定的,并且是根据列声明的最大长度,这可能导致内存缓冲区(example)的低效使用。虽然SSIS包开发人员可以声明一个比源更小的列大小,但这个分析最好先预先完成并在那里强制执行。 回到SQL Server引擎本身,类似的情况是,在计算为SORT操作分配的内存授权时,SQL Server假定varchar(x)列平均消耗x/2字节。 如果您的大多数varchar列都比这更完整,则可能导致sort操作溢出到tempdb。 在您的情况下,如果您的varchar列被声明为8000字节,但实际上内容远远少于您的查询将分配它不需要的内存,这显然是低效的,并且可能导致等待内存授予。 SQL Workshops Webcast 1 downloadable from here的第2部分对此进行了介绍,或者参见下文。
use tempdb;
CREATE TABLE T(
id INT IDENTITY(1,1) PRIMARY KEY,
number int,
name8000 VARCHAR(8000),
name500 VARCHAR(500))
INSERT INTO  T 
(number,name8000,name500)
SELECT number, name, name /*<--Same contents in both cols*/
FROM master..spt_values
SELECT id,name500
FROM T
ORDER BY number
Screenshot
SELECT id,name8000
FROM T
ORDER BY number
Screenshot

peum

赞同来自:

理想情况下,您希望小于此值,缩小到合理大小的长度(500不合理大小),并确保在数据太大并发送有用错误时捕获客户端验证。 虽然varchar实际上不会为未使用的空间在数据库中保留空间,但我记得SQL Server的版本有一个关于数据库行的snit比一些字节数更宽(不记得确切的计数)并实际抛出无论数据不合适。为SQL Server内部的内容保留了一定数量的这些字节。

desse

赞同来自:

从处理的角度来看,使用varchar(8000)和varchar(500)并没有什么区别。定义一个字段应该保持的最大长度并使varchar成为一个长度,这更像是一种“良好实践”。它可用于协助数据验证。例如,将州名缩写为2个字符或邮政/邮政编码为5或9个字符。当您的数据与字段长度很关键的其他系统或用户界面(例如大型机平面文件数据集)进行交互时,这曾经是一个更重要的区别,但现在我认为它比其他任何东西都更习惯。

xqui

赞同来自:

除了最佳实践(BBlake的答案)

  • 使用DDL收到有关最大行大小(8060)字节和索引宽度(900字节)的警告
  • 如果超过这些限制,DML将会死亡
  • ANSI PADDING ON是默认设置,因此您最终可能会存储一大堆空白

qporro

赞同来自:

对于较不明显的大型列而言,存在一些缺点,可能会稍后发现:

  • 您在INDEX中使用的所有列 - 不得超过900字节
  • ORDER BY子句中的所有列不得超过8060个字节。这有点难以掌握,因为这仅适用于某些列。有关详细信息,请参阅SQL 2008 R2 Row size limit exceeded)
  • 如果总行大小超过8060字节,则会出现该行的“页面溢出”。这可能会影响性能(一个页面是SQLServer中的一个分配单元,固定为8000字节+一些开销。超过这个并不会很严重,但它是显而易见的,你应该尽量避免使用它)
  • 许多其他内部数据结构,缓冲区以及最后 - 至少您自己的变量和表变量都需要镜像这些大小。尺寸过大,过多的内存分配会影响性能
作为一般规则,尝试保持列宽。如果它成为问题,您可以轻松扩展它以满足需求。如果您稍后发现内存问题,稍后缩小宽列可能变得不可能而不会丢失数据,您将不知道从哪里开始。 在您的商家名称示例中,请考虑显示它们的位置。真的有500个字符的空间吗?如果没有,那么存储它们就没什么意义了。 http://en.wikipedia.org/wiki/List_of_companies_of_the_United_States列出了一些公司名称,最大值约为50个字符。所以我最多使用100作为列。也许更像80。