每次设置新的SQL表或向现有表中添加新的varchar列时,我都想知道一件事:length的最佳值是什么.

So, lets say, you have a column called name of type varchar. So, you have to choose the length. I cannot think of a name > 20 chars, but you will never know. But instead of using 20, I always round up to the next 2^n number. In this case, I would choose 32 as the length. I do that, because from an computer scientist point of view, a number 2^n looks more even to me than other numbers and I'm just assuming that the architecture underneath can handle those numbers slightly better than others.

另一方面,当您 Select 创建varchar列时,MSSQL server会将默认长度值设置为50.这让我想起了它.为什么是50?它只是一个随机数,还是基于平均列长度,还是什么?

不同的SQL Server实现(如MySQL、MSSQL、Postgres等)也可能是(或者可能是)具有不同的最佳列长度值.

推荐答案

据我所知,没有一个DBMS有任何"优化"可以使长度为2^nVARCHAR比长度为max的不是2的幂的DBMS性能更好.

我认为早期的SQL Server版本实际上对待长度为255的VARCHAR与最大长度更高的VARCHAR是不同的.我不知道情况是否仍然如此.

对于几乎所有的DBMS,所需的实际存储只取决于输入的字符数,而不是定义的max个长度.因此,从存储的Angular 来看(很可能也是从性能的Angular 来看),将列声明为VARCHAR(100)VARCHAR(500)没有任何区别.

您应该将VARCHAR列的max长度视为一种约束(或业务规则),而不是一种技术/物理因素.

对于PostgreSQL,最好的设置是使用text而不受长度限制,使用CHECK CONSTRAINT将字符数限制在业务需要的范围内.

如果需求发生变化,那么改变check约束比改变表要快得多(因为表不需要重写)

同样的道理也适用于甲骨文和其他公司——不过甲骨文的数字应该是VARCHAR(4000)而不是text.

我不知道SQL Server中的VARCHAR(max)VARCHAR(500)之间是否存在物理存储差异.但显然,与varchar(8000)相比,使用varchar(max)会对性能产生影响.

this link(埃尔文·布兰斯特特发表 comments )

Edit 2013-09-22

关于bigown的 comments :

在9.2之前的Postgres版本中(在我写初始答案时没有),对列定义did的更改会重写整个表,参见示例here.由于9.2不再是这种情况,一个快速测试证实,为一个有120万行的表增加列大小实际上只需要0.5秒.

对于甲骨文来说,从改变一个大表的varchar列所需的时间来看,这似乎也是正确的.但我找不到这方面的任何参考资料.

对于MySQL the manual says"In most cases, 101 makes a temporary copy of the original table".我自己的测试也证实了这一点:在一个有120万行的表上运行ALTER TABLE(与我在Postgres测试中的测试相同)以增加列的大小需要1.5分钟.然而,在MySQL中,您可以使用"变通方法"来使用判断约束来限制列中的字符数.

对于SQL Server,我找不到关于这一点的明确声明,但增加varchar列大小(同样是上面的120万行表)的执行时间表明发生了no次重写.

Edit 2017-01-24

看来我对SQL Server的看法(至少部分)是错的.请参阅this answer from Aaron Bertrand,它表明nvarcharvarchar列的声明长度对性能有巨大影响.

Mysql相关问答推荐

正则表达式转换为MYSQL格式

根据上一行S列结果计算列的查询

LaravelEloquent ToSql()缺少连接表

无法连接到扩展坞MySQL Unix套接字

无法确定查询逻辑

没有 ORDER BY 的查询性能很高,有 ORDER BY 的查询速度慢得像爬行一样

在 MySQL 中,如何对 LIKE 查询进行批量更新,删除字符?

仅当 SELECT 语句在 MySQL 中给出空集时才执行 UPDATE 语句

Select 最高等级最多的部门名称

MySQL Join 查询位置从订单

按年份范围 SQL 查询分组

MySQL IF() 函数根据指定条件执行代码块

保存SQL查询的中间结果

MYSQL LOAD DATA INFILE 语句适用于工作台,但不适用于 python

MySQLi count(*) 总是返回 1

何时在 mysql 中使用 TEXT 而不是 VARCHAR

基于字符串动态创建 PHP 对象

#1146 - 表 'phpmyadmin.pma_recent' 不存在

MySQL 在每个唯一值第一次出现时 Select 行

与 MySql 的连接正在自动中止.如何正确配置Connector/J?