据我所知,没有DBMS有任何“优化”可以使长度VARCHAR
为a的2^n
性能比max
长度为2的幂的性能更好。
我认为早期的SQL Server版本实际上将VARCHAR
255的长度与最大长度较高的长度区别对待。我不知道情况是否仍然如此。
对于几乎所有的DBMS,所需的实际存储空间仅取决于您放入其中的字符数,而不取决于max
您定义的长度。因此,从存储的角度(也可能是性能的角度)而言,将列声明为VARCHAR(100)
还是都没有任何区别VARCHAR(500)
。
您应该max
将为VARCHAR
列提供的长度看作是一种约束(或业务规则),而不是技术/实际的事物。
对于PostgreSQL来说,最好的设置是使用text
不受长度限制CHECK CONSTRAINT
的字符集,它将字符数限制为您的业务需要。
如果该要求发生变化,则更改检查约束比更改表要快得多(因为无需重写表)
可以对Oracle和其他对象应用相同的方法-在Oracle中,它VARCHAR(4000)
不是,text
而是。
我不知道SQL Server VARCHAR(max)
和VARCHAR(500)
SQL Server 之间是否存在物理存储差异。但varchar(max)
与相比,使用显然会对性能产生影响varchar(8000)
。
看到此链接(由Erwin Brandstetter发表评论)
编辑2013-09-22
关于bigown的评论:
在9.2之前的Postgres版本中(我写初始答案时不可用),对列定义的更改确实重写了整个表,请参见例如此处。从9.2开始,情况就不再如此,快速测试证实,增加具有120万行的表的列大小实际上仅用了0.5秒。
对于Oracle来说,从更改大表的varchar
列所需的时间来看,这似乎也是正确的。但是我找不到任何参考。
对于MySQL ,手册上写着 “ 在大多数情况下,ALTER TABLE
为原始表创建一个临时副本 ”。我自己的测试证实了:ALTER TABLE
在具有120万行的表上运行(与我对Postgres的测试相同)以增加列的大小需要1.5分钟。但是,在MySQL中,您不能使用“替代方法”来使用检查约束来限制列中的字符数。
对于SQL Server,我对此没有找到明确的声明,但是增加varchar
列的大小(同样是上表的120万行表)的执行时间表明没有重写。
编辑2017-01-24
似乎我(至少部分地)对SQL Server错误。请参阅Aaron Bertrand的答案,该答案表明a nvarchar
或varchar
column 的声明长度对性能有很大的影响。