首页 > 基础资料 博客日记

补充MySQL官网知识--解锁Online VARCHAR字段扩展与Index的关系

2026-06-09 23:30:02基础资料围观3

文章补充MySQL官网知识--解锁Online VARCHAR字段扩展与Index的关系分享给大家,欢迎收藏极客资料网,专注分享技术知识

大家可以先看本文的结论【即 4. 总结】,如有兴趣再顺读。

1. Online DDL Support for Column Operations

OperationIn PlaceRebuilds TablePermits Concurrent DMLOnly Modifies Metadata
Adding a column Yes Yes Yes* No
Dropping a column Yes Yes Yes No
Renaming a column Yes No Yes* Yes
Reordering columns Yes Yes Yes No
Setting a column default value Yes No Yes Yes
Changing the column data type No Yes No No
Extending VARCHAR column size Yes No Yes Yes
Dropping the column default value Yes No Yes Yes
Changing the auto-increment value Yes No Yes No*
Making a column NULL Yes Yes* Yes No
Making a column NOT NULL Yes* Yes* Yes No
Modifying the definition of an ENUM or SET column Yes No Yes Yes

2. Extending VARCHAR column size

OperationIn PlaceRebuilds TablePermits Concurrent DMLOnly Modifies Metadata
Extending VARCHAR column size Yes No Yes Yes

修改的语法如下

ALTER TABLE tbl_name CHANGE COLUMN c1 c1 VARCHAR(255), ALGORITHM=INPLACE, LOCK=NONE;

The number of length bytes required by a VARCHAR column must remain the same. For VARCHAR columns of 0 to 255 bytes in size, one length byte is required to encode the value. For VARCHAR columns of 256 bytes in size or more, two length bytes are required. As a result, in-place ALTER TABLE only supports increasing VARCHAR column size from 0 to 255 bytes, or from 256 bytes to a greater size. In-place ALTER TABLE does not support increasing the size of a VARCHAR column from less than 256 bytes to a size equal to or greater than 256 bytes. In this case, the number of required length bytes changes from 1 to 2, which is only supported by a table copy (ALGORITHM=COPY). For example, attempting to change VARCHAR column size for a single byte character set from VARCHAR(255) to VARCHAR(256) using in-place ALTER TABLE returns this error:

ALTER TABLE tbl_name ALGORITHM=INPLACE, CHANGE COLUMN c1 c1 VARCHAR(256);
ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change
column type INPLACE. Try ALGORITHM=COPY.

注意:The byte length of a VARCHAR column is dependant on the byte length of the character set.

Decreasing VARCHAR size using in-place ALTER TABLE is not supported. Decreasing VARCHAR size requires a table copy (ALGORITHM=COPY).

---摘自官网:https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html#online-ddl-column-operations

 

注意:在有关Extending VARCHAR column size的说明中 ,官网没有涉及字段Index的内容。很可惜。

3. 不一样的风景

3.1 场景

不知读者是否已遇到或者注意到,给表的字段扩展长度有时候很快,而有时候有需要消耗几分钟。排除掉官网提到的字段长度encode临界值的修改---字节256,还是解释不了为什么会执行那么久。

按照官网的说明,在相同的encode字节要求下(1--255;256及以上),  这个操作只是修改了元数据,不需要Rebuilds Table,应该瞬间完成(或者说3S内)。那么执行了几分钟,是不是很有些因素是官网没有提到的。

3.2 举例说明

MySQL版本 5.7.21
Server配置 8核24G;VSAN盘
表--qq_order_cust

记录数:760W

Data length:2.8G

Index length:1.5G

Table Size:4.3G 

修改的列

列1:product_name VARCHAR(64)

列1:per_type VARCHAR(16)

table collation utf8mb4_general_ci

 

SQL语句1

ALTER TABLE qq_order_cust ALGORITHM=INPLACE, CHANGE COLUMN product_name product_name VARCHAR(128);

product_name列的长度由64调整到128,  这条语句执行了247S,4分钟。--这个情况是用官网知识解释不了的,不符合预期。

SQL语句2

ALTER TABLE qq_order_cust ALGORITHM=INPLACE, CHANGE COLUMN per_type per_type VARCHAR(32);

per_type列的长度由16调整到32,这条语句 瞬间完成,不到1S。---符合预期

有同学可能会认为会不会数据已缓存到内存中了,所以SQL语句2执行快了很多。这个我们排除掉了。--我们执行了语句3--将product_name 由128调整到132--,还是执行240多秒,所以,语句2执行快很快和数据内存无关。

按照官网的知识,上面两个语句都是应该瞬间执行完成的。

这是怎么回事?难道是随机的?这以后怎么评估执行时间和影响呢?

3.3 灵光乍现

反复比较,盯着表创建语句看了N遍,忽然发现 耗时久的那个字段上有index,是两个独立的索引Index,即这个字段和其它不同的字段分别组合了Composite Index。

难道耗时久,和index有关。

抱着尝试的心态,我们决定试下。

因为是验证环境,保存语句,然后,我们直接将这两个有关 product_name 的index直接删除掉了。

再执行 SQL4 

ALTER TABLE qq_order_cust ALGORITHM=INPLACE, CHANGE COLUMN product_name product_name VARCHAR(132);

长度由128调整到132,这次瞬间完成了,不到1S。---符合预期

惊喜,那就再验证一次

SQL5

ALTER TABLE qq_order_cust ALGORITHM=INPLACE, CHANGE COLUMN product_name product_name VARCHAR(156);

这是还是瞬间完成。---符合预期

基于以上的验证,可以得出以下结论

结论: 修改有索引的字段的长度,不会瞬间完成,不是Only Modifies Metadata 。这是官网上没提到的。

3.4 继续探究

实验尚未。刚才说了,在两个关联索引的条件下耗时247S,如果只有一个关联index,不会快些。【注意:所谓的关联index,是指和指定字段有关联,和要修改的字段有关联】

我们想到这一点,已经欣欣然了,忍不住继续测试下去。

先仅修复其中一个index。在此条件下执行SQL6

ALTER TABLE qq_order_cust ALGORITHM=INPLACE, CHANGE COLUMN product_name product_name VARCHAR(186);

SQL耗时变成了131S。耗时是原来的一半左右。------符合预期,小小激动。

继续修复第二个关联index,执行SQL7

ALTER TABLE qq_order_cust ALGORITHM=INPLACE, CHANGE COLUMN product_name product_name VARCHAR(258);

此时,SQL耗时变成了242S。

基于以上的验证,可以得出以下结论

结论:修改有索引的字段的长度,其耗时 和 这个字段上索引的个数正相关;索引越多,耗时越久。这是官网上没提到的。

4. 总结

1. Extending VARCHAR column size,字段的字节长度(255-->256)是个临界值。注意是字节,如果选用的字符集是utf8mb4,VARCHAR字段对应的VARCHAR(63)-->VARCHAR(64)是临界值。这点官网上有提到。

2.修改有索引的字段的长度,不会瞬间完成,不是Only Modifies Metadata。这是官网上没提到的。

3.修改有索引的字段的长度,其耗时 和 这个字段上索引的个数正相关;索引越多,耗时越久。这是官网上没提到的。

4. 官网中 字段长度扩展不Rebuilds Table、Only Modifies Metadata,这儿应该有个特指--仅指的是聚簇索引(Clustered Index),不包含辅助index(也被称为二级索引非聚簇索引)。因为案例中的4分钟,应该是在重整字段相关的辅助ndex,通过监控也可以看到4分钟内有大量的IO操作。这是官网上没提到的。

 

备注

1.此测试是在MySQL 5.7.21 版本下验证的,MySQL8.0 版本下是什么表现,尚未验证。

2.本次字段扩展实验用的是utf8mb4字符集下VARCHAR类型。

 


文章来源:https://www.cnblogs.com/xuliuzai/p/20408033
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云