将 varchar(lower value) 数据类型更改为 varchar(higher value) 之间的区别,反之亦然

difference between changing varchar(lower value) datatype to varchar(higher value) and vice versa

我正在使用 MySQL 5.7.17

当我将大型测试 table 的数据类型从 varchar(45) 更改为 varchar(50) 时,只用了不到一秒的时间就完成了。

我找不到很好的文档来解释为什么这一切发生得如此之快。请帮忙。

(我们将在我们的巨大生产中将数据类型从 varchar(45) 更改为 varchar(50) table,这将有助于我们计算为此所需的停机时间。)

This one should be faster, there's no truncation of values because you are increasing the length.

But I suggest to make a copy of existing table, after changing the length, you can rename the tables. Renaming of tables should be faster.

A table 有一个“定义”(CREATE TABLE...),它有数据和索引。

如果 ALTER 可以在不改变数据存储方式的情况下执行,那么它可以(在大多数情况下,以及在最近的版本中)通过更改定义而不触及实际数据来实现。

那么,让我们看看 VARCHAR(N) 列是如何存储的:

简称定义(即对于小N):

* 1-byte length field
* a variable number of bytes to hold the actual _characters_

对于更大的列(N=256 当然符合条件):

* 2-byte length field
* a variable number of bytes to hold the actual characters

因此,从 N=40 切换到 N=50 不需要触及数据,但我认为从 N=45 切换到 N=266 需要重写所有数据。

(我对 N 有点含糊,因为一个“字符”可以占用多个“字节”,具体取决于 COLLATION。)

也许最慢的 ALTER 是如果您更改 PRIMARY KEY。这需要重新排列数据,因为它是由 PK 排序的,并且需要重建所有二级索引,因为它们包含 PK 的副本。

频谱中间是一些 INDEX 操作。 DROP INDEX 非常便宜——从定义中删除,然后清理它消耗的 space。 ADD INDEX 成本更高,因为它需要填充一个新的 BTree 来保存索引。同时,数据和任何其他二级索引可以保持不变。但是,该代码必然很棘手——如果在构建索引时修改了行怎么办。