长列如何影响性能和磁盘使用率?


26

在我们当前的项目中,它经常发生,我们需要将列扩展几个字符。从varchar(20)varchar(30)等等。

实际上,这到底有多重要?优化效果如何?正常的“输入”字段只允许100或200甚至500个字符的影响是什么?一封电子邮件只能包含320个字符,所以好吧-那里有一个很好的限制。但是,如果将其设置为200,我会得到什么,因为我希望电子邮件地址不会超过此数目。

通常,我们的表的行数不超过100.000,最多不超过20或30列。

我们现在使用SQL Server 2008,但是了解不同的DB如何处理此问题将很有趣。

如果影响非常小-就像我期望的那样,这将有助于获得一些好的论据(通过链接进行备份?)来说服我的DBA,这种长距离偏执并不是真正必要的。

如果是这样,我在这里学习:-)

Answers:


12

对于您的问题的具体答案(至少对于Oracle和其他数据库而言)是字段的长度无关紧要,仅取决于数据的长度。但是,这不应用作决定是否将字段设置为最大允许长度的决定因素。在最大化字段大小之前,还应考虑以下其他问题。

格式化 任何基于字段大小格式化数据的客户端工具都将需要特殊的格式化注意事项。例如,默认情况下,Oracle的SQL * Plus将显示Varchar2列的最大大小,即使数据只有一个字符长。比较…

create table f1 (a varchar2(4000), b varchar2(4000));
create table f2 (a varchar2(5), b varchar2(5));
insert into f1 values ('a','b');
insert into f2 values ('a','b');
select * from f1;
select * from f2;

错误数据 字段的长度提供了一种额外的机制来捕获/防止错误数据。接口不应尝试在100个字符的字段中插入3000个字符,但是如果将该字段定义为4000个字符,则可能会这样。该错误不会在数据输入阶段捕获,但是当另一个应用程序尝试处理数据并阻塞时,系统可能会进一步陷入困境。例如,如果您以后决定对Oracle中的字段建立索引,则将超出最大密钥长度(取决于块大小和串联)。看到…

create index i1 on f1(a);

内存 如果客户端应用程序使用最大大小分配内存,则该应用程序将分配比所需数量更多的内存。为了避免这种情况,必须进行特殊考虑。

文档 字段的大小提供了有关数据的文档的另一个数据点。我们可以调用所有表t1,t2,t3等,以及所有字段f1,f2,f3等,但是通过指定有意义的名称,我们可以更好地理解数据。例如,如果一家在美国有客户的公司的地址表中有一个名为“州”的字段,该字段是两个字符,则我们希望其中包含两个字符的州缩写。另一方面,如果该字段为一百个字符,我们可能期望完整的州名进入该字段。


综上所述,为变革做好准备似乎是审慎的做法。仅仅因为您今天所有的产品名称都可以包含20个字符,并不意味着它们总是会适合。不要过分提高并使其达到1000,但要为合理的扩展留出空间。



文档是您在此处添加的一个不错的文档,我在其他任何地方都没有看到过。
jeteon '18

9

这是您的一个很好的起点。

http://www.sqlskills.com/BLOGS/KIMBERLY/post/Disk-space-is-cheap.aspx

我可能误解了您的原始问题。让我看看是否可以找到其他链接供您参考。

这是有关数据类型选择的良好参考:http : //sqlfool.com/2009/05/performance-considerations-of-data-types/

从varchar(20)更改为varchar(30)似乎很小,但是您需要更多地了解数据库结构的工作方式,以便了解潜在的问题。例如,转到varchar(30)可能会使您越过列的临界点(应使用全部30个字节),从而可以存储在一页上(小于8060个字节)。这将导致使用的磁盘空间增加,性能下降,甚至导致事务日志的额外开销。

这是数据库结构的链接:http : //technet.microsoft.com/zh-cn/sqlserver/gg313756.aspx

这是用于页面拆分和trx日志记录的代码:http : //sqlskills.com/BLOGS/PAUL/post/How-expensive-are-page-splits-in-terms-of-transaction-log.aspx

高温超导


7

我以为我会分享另一个有趣的观点,我在以下SO问题中发现了这一点:

/programming/148398/are-there-any-disadvantages-to-always-using-nvarcharmax

原始答案:尼克·卡瓦迪亚斯(Nick Kavadias)

不使用max或text字段的原因是,即使使用SQL Server Enterprise Edition,也无法执行[online index rebuilds] [1],即REBUILD WITH ONLINE = ON。

[1]:http : //msdn.microsoft.com/zh-cn/library/ms188388%28SQL.90%29.aspx “在线索引重建”

我认为在任意添加n / varchar(max)列时这是一个很大的缺点,并且根据MS网站,这种限制进行联机索引重建的条件仍然存在于SQL Server 2008、2008 R2和Denali中。因此它并不特定于SQL Server 2005。

谢谢杰夫


6

在某些情况下,您为varchar字段分配的空间量将影响为内存中排序分配的内存量。

我在SQLWorkshops.com上的演示文稿令人发指,该演示文稿讨论了由于没有为char / varchar字段分配足够的内存而将排序依据溢出到tempdb的情况。

http://webcasts2.sqlworkshops.com/webcasts.asp

该网络广播还作为文章在以下网站上进行了介绍:

http://www.mssqltips.com/tip.asp?tip=1955

请注意,在此演示文稿中,要排序的列不是char / varchar列,但是在某些情况下,为内存中的varchar列分配的空间量会使查询性能有所不同。


4

将ANSI_PADDING设置为ON?

您最终会遇到很多尾随空格...


3

它仅与磁盘空间和字符长度有关。当然,对char数据类型的搜索以及对这些数据类型的索引的搜索将比整数慢,但这是另一个讨论。

Varchar数据类型是“可变”数据类型,因此,如果您设置了varchar(500)限制,则该限制为该字段的最大字符长度。最小长度可以在0到500之间。另一方面,要求的磁盘空间对于10、30或500个字符字段将有所不同。

有时我对数据类型varchar(800)和空值进行了测试,使用了17个字节,并且对于插入的每个字符又添加了一个字节。例如,一个400字符串在磁盘上使用了417个字节。


3

我不认为,使用varchar(20)或varchar((8000)列创建的表之间没有任何区别,只要实际最大长度为<= 20。

另一方面,在某些情况下,为用户提供存储更长字符串的可能性可能会鼓励他们这样做。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.