Mysql8秒级加字段_MySQL8.0大表秒加字段

前言:

很早就听说 MySQL8.0 支持快速加列,可以实现大表秒级加字段。笔者自己本地也有8.0环境,但一直未进行测试。本篇文章我们就一起来看下 MySQL8.0 快速加列到底要如何操作。

1.了解背景信息

表结构的变更是业务运行过程中比较常见的需求之一,在 MySQL 的环境中,可以使用 Alter 语句来完成这些操作,这些 Alter 语句对应的操作通常也称之为 DDL 操作。通常情况下大表的 DDL 操作都会对业务有很明显的影响,需要在业务空闲,或者是维护的时候做。MySQL 5.7 支持 Online DDL,大部分 DDL 不影响对表的读取和写入,但是依然会消耗非常多的时间,且占用额外的磁盘空间,并会造成主从延迟。所以大表 DDL 仍是一件令 DBA 头痛的事。

听闻 MySQL 8.0 解决了这件令 DBA 头痛的事,那让我们来详细了解下吧。想了解新功能,最简单的方法就是查阅官方文档。查阅官方文档得知,快速加列即 Instant Add Column ,该功能自 MySQL 8.0.12 版本引入,是由腾讯游戏DBA团队贡献。注意一下,此功能只适用于 InnoDB 表。

2.快速加列测试

快速加列采用的是 instant 算法,使得添加列时不再需要 rebuild 整个表,只需要在表的 metadata 中记录新增列的基本信息即可。在 alter 语句后增加 ALGORITHM=INSTANT 即代表使用 instant 算法, 如果未明确指定,则支持 instant 算法的操作会默认使用。如果 ALGORITHM=INSTANT 指定但不支持,则操作立即失败并显示错误。

关于列的 DDL 操作,是否支持 instant 等算法,官方文档给出了一个表格,现整理如下,星号表示不是全部支持,有依赖项。操作InstantIn PlaceRebuilds Table允许并发DML仅修改元数据添加列Yes*YesNo*Yes*No

删除列NoYesYesYesNo

重命名列NoYesNoYes*Yes

更改列顺序NoYesYesYesNo

设置列默认值YesYesNoYesYes

更改列数据类型NoNoYesNoNo

扩展VARCHAR列大小NoYesNoYesYes

删除列默认值YesYesNoYesYes

更改自动增量值NoYesNoYesNo*

设置列为nullNoYesYes*YesNo

设置列not nullNoYes*Yes*YesNo

修改ENUM/SET列的定义YesYesNoYesYes

instant 算法使用最广泛的应该是添加列了,可以看到使用该算法还是有些限制的,一些限制如下:如果 alter 语句包含了 add column 和其他的操作,其中有操作不支持 instant 算法的,那么 alter 语句会报错,所有的操作都不会执行。

只能顺序加列, 仅支持在最后添加列,而不支持在现有列的中间添加列。

不支持压缩表,即该表行格式不能是 COMPRESSED。

不支持包含全文索引的表。

不支持临时表。

不支持那些在数据字典表空间中创建的表。

说的再多不如实际来测下,下面我们以 8.0.19 版本为例来实际验证下:# 利用sysbench生成一张1000W的大表

mysql> select version();

+-----------+| version() |

+-----------+| 8.0.19    |

+-----------+1 row in set (0.00 sec)

mysql> select count(*) from sbtest1;

+----------+| count(*) |

+----------+| 10000000 |

+----------+# 增加无默认值的列

mysql> alter table sbtest1 add column col1 varchar(20), algorithm=instant;

Query OK, 0 rows affected (0.63 sec)

Records: 0  Duplicates: 0  Warnings: 0

# 增加有默认值的列

mysql> alter table sbtest1 add column create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', algorithm=instant;

Query OK, 0 rows affected (0.58 sec)

Records: 0  Duplicates: 0  Warnings: 0

# 不显式指定instant算法

mysql> alter table sbtest1 add column col2 varchar(20);

Query OK, 0 rows affected (0.55 sec)

Records: 0  Duplicates: 0  Warnings: 0

# 设置列的默认值

mysql> alter table sbtest1 alter column col1 set default 'sql',algorithm=instant;

Query OK, 0 rows affected (0.02 sec)

Records: 0  Duplicates: 0  Warnings: 0

# 指定In Place算法添加列,(5.7版本添加列使用该算法)

mysql> alter table sbtest1 add column col_inplace varchar(20),algorithm=inplace;

Query OK, 0 rows affected (1 min 23.30 sec)

Records: 0  Duplicates: 0  Warnings: 0

通过以上测试,我们可以发现,使用 instant 算法添加列基本都在 1s 内完成,对于大表来说这个速度是非常快的,业务基本无感知。当使用 5.7 版本的 inplace 算法时,则添加列的时间上升至数分钟。对比看来 8.0 版本的快速加列功能确实非常实用!

总结:

虽然快速加列存在一些限制, instant 算法也只适用于部分 DDL 操作,但 8.0 的这项新功能已经足以令人兴奋,很大程度上解决了大表加字段的大难题。通过这篇文章,希望各位能了解到这项新功能,是不是想升级到 8.0 了呢,可以着手准确起来了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 8.0中,sql_mode=only_full_group_by是一种SQL模式,它使得在执行GROUP BY时,SELECT列中的非聚合列必须出现在GROUP BY子句中。这是为了确保查询结果的准确性和一致性。然而,这也可能导致一些查询出错,例如在SELECT列中包含了非聚合列并且没有在GROUP BY子句中列出。引用 要解决这个问题,有两种方法可以尝试。首先,你可以修改全局设置,这样对于新建的数据库会有效。你可以执行以下命令:SET @@global.sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; 引用 另外,如果你想对已存在的数据库生效,你需要在对应的数据库下执行以下命令:SET sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; 引用 举个例子,如果你想在mt_user中根据mobile字段进行分组,并且只显示那些mobile字段的值重复超过一次的记录,你可以执行以下查询:select id,mobile from mt_user group by mobile having count(1)>1; 但是,由于sql_mode设置为only_full_group_by,这个查询会报错,因为SELECT列中的id字段没有在GROUP BY子句中列出。引用 因此,为了解决这个问题,你可以按照上述方法修改sql_mode设置,将only_full_group_by从中移除。这样就可以执行这个查询并得到正确的结果了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [MySQL 8.0 修改 sql_mode=only_full_group_by](https://blog.csdn.net/qq_35349114/article/details/108277591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值