1. 问题背景

MySQL版本:8.0.30

测试表数据量:200万

在 MySQL 中,研发人员最初执行了以下 SQL 语句,向表 t_email 中添加了一个允许为 NULL 的列 id3,并设置了默认值为 0:

ALTER TABLE t_email ADD COLUMN id3 INT NULL DEFAULT 0;

随后发现需要将该列修改为 NOT NULL,于是尝试执行以下语句:

ALTER TABLE t_email MODIFY COLUMN id3 INT NOT NULL DEFAULT 0;

然而,直接修改时发现无法使用 ALGORITHM=INSTANT,只能使用 ALGORITHM=INPLACE 或 ALGORITHM=COPY,导致操作耗时较长(14.67 秒)。

后续的测试中改为先删除列,再重新添加列的方式,成功使用了 ALGORITHM=INSTANT,速度显著提升。

2. 问题分析

  • ALGORITHM=INSTANT 的限制

    8.0.12 新添加了INSTANT算法。

    MySQL 的 ALGORITHM=INSTANT 是一种快速修改表结构的算法,但它仅支持特定的 DDL 操作。

    添加和删除列是支持的,修改列的NULL或NOT NULL不支持.

    在尝试将列从 NULL 修改为 NOT NULL 时,ALGORITHM=INSTANT 不支持此操作,因此 MySQL 只能使用 ALGORITHM=INPLACE 或 ALGORITHM=COPY,导致操作耗时较长。

    Table 17.18 Online DDL Support for Column Operations
  • ALGORITHM=INPLACE 和 ALGORITHM=COPY 的开销

    ALGORITHM=INPLACE:在表上直接修改元数据,但仍可能需要重建表数据。

    ALGORITHM=COPY:创建新表并复制数据,完成后删除旧表。这种方式通常较慢,尤其是在表数据量较大时。
  • 删除列并重新添加列的优化

    通过删除列并重新添加列的方式,可以绕过 MODIFY COLUMN 的限制,直接使用 ALGORITHM=INSTANT,从而显著提升性能。

3. 解决方案

  • 原始方案

    添加允许为NULL的列id3,并设置了默认值为0
mysql> alter table t_email add column id3 int null default 0;
Query OK, 0 rows affected (0.86 sec)
Records: 0 Duplicates: 0 Warnings: 0

将列的属性修改为不允许为NULL,其他不变

mysql> alter table t_email modify column id3 int not null default 0;
Query OK, 0 rows affected (14.67 sec)
Records: 0 Duplicates: 0 Warnings: 0
  • 优化后的方案

    添加允许为NULL的列id3,并设置了默认值为0。
mysql> alter table t_email add column id3 int null default 0, ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.85 sec)
Records: 0 Duplicates: 0 Warnings: 0

删除id3列,耗时0.98秒。

mysql> alter table t_email drop column id3, ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.98 sec)
Records: 0 Duplicates: 0 Warnings: 0

重新添加id3列,将属性改为NOT NULL,并设置了默认值为0,耗时0.68秒。

mysql> alter table t_email add column id3 int not null default 0, ALGORITHM=INSTANT;
Query OK, 0 rows affected (0.68 sec)
Records: 0 Duplicates: 0 Warnings: 0

4. 总结

ALGORITHM=INSTANT 的限制:不支持修改列的 NULL 属性。仅支持特定的 DDL 操作(如添加列、删除列)。虽然不会操作不会阻塞DML,但是在DDL刚开始和结束时,都要获取MDL,如果这两个阶段表上有事务,DDL会因为获取不到MDL而被阻塞。

优化思路:对于不支持 ALGORITHM=INSTANT 的操作,可以尝试通过删除列并重新添加列的方式绕过限制。这种方式在表数据量越大时,性能提升越明显。

从 14 秒到 1 秒:MySQL DDL 性能优化实战的更多相关文章

  1. Mysql数据库性能优化(一)

    参考 http://www.jb51.net/article/82254.htm 今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要 ...

  2. mysql数据库性能优化(包括SQL,表结构,索引,缓存)

    优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...

  3. MySQL数据库性能优化的关键参数(转)

    我们在进行数据库管理和开发中经常会遇到性能问题,这就涉及到MySQL的性能优化.通过在网络上查找资料和笔者自己的尝试,我认为以下系统参数是比较关键的: 关键参数一:back_log 要求 MySQL ...

  4. MySQL 数据库性能优化之缓存参数优化

    在平时被问及最多的问题就是关于 MySQL 数据库性能优化方面的问题,所以最近打算写一个MySQL数据库性能优化方面的系列文章,希望对初中级 MySQL DBA 以及其他对 MySQL 性能优化感兴趣 ...

  5. 到底该不该使用存储过程 MySQL查询性能优化一则

    到底该不该使用存储过程   看到<阿里巴巴java编码规范>有这样一条 关于这条规范,我说说我个人的看法 用不用存储过程要视所使用的数据库和业务场景而定的,不能因为阿里巴巴的技术牛逼,就视 ...

  6. DB-MySQL:MySQL 语句性能优化

    ylbtech-DB-MySQL:MySQL 语句性能优化 1.返回顶部 1. MySQL概述1.数据库设计 3范式2.数据库分表分库---会员系统() 水平分割(分页如何查询)MyChar .垂直3 ...

  7. MySQL数据库性能优化与监控实战(阶段四)

    MySQL数据库性能优化与监控实战(阶段四) 作者 刘畅 时间 2020-10-20 目录 1 sys数据库 1 2 系统变量 1 3 性能优化 1 3.1 硬件层 1 3.2 系统层 1 3.3 软 ...

  8. 1229【MySQL】性能优化之 Index Condition Pushdown

    转自http://blog.itpub.net/22664653/viewspace-1210844/  [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...

  9. 深入理解MySQL开发性能优化.pptx

    深入理解MySQL开发性能优化.pptx,依旧上传baidu pan http://pan.baidu.com/s/1jIwGslS,视频暂未出,培训完成后会更新.

  10. MySQL 数据库性能优化之索引优化

    接着上一篇 MySQL 数据库性能优化之表结构,这是 MySQL数据库性能优化专题 系列的第三篇文章:MySQL 数据库性能优化之索引优化 大家都知道索引对于数据访问的性能有非常关键的作用,都知道索引 ...

随机推荐

  1. CF926 Div.2

    C. Sasha and the Casino 赌场规则:如果下注 \(y(y > 0)\) 元,如果赢了则除了 \(y\) 元外,额外获得 \(y \times (k - 1)\) 元,否则则 ...

  2. 论文泛读《T-Miner: A Generative Approach to Defend Against Trojan Attacks on DNN-based Text Classification》

    发表时间:2021 期刊会议:30th USENIX Security Symposium 论文单位:Virginia Tech 论文作者:Ahmadreza Azizi,Ibrahim Asadul ...

  3. pdf.js 笔记

    1.介绍 官方文档,pdf.js是由mozilla开源的js库,用于在web环境中渲染和显示pdf文档 目前,绝大多数PC浏览器都已经内置了pdf阅读器,能够直接预览pdf文件(内置了pdf.js), ...

  4. 19号CSS学习

    一.CSS的复合选择器 更高效的选择目标元素. 后代选择器.子选择器.并集选择器.伪类选择器等. 1.后代选择器 可以选择父元素里的子元素. 又称包含选择器. 必须是空格,必须是后代,ul li {c ...

  5. Postman无法启动

    前情 最近在捣鼓node.js,需要一个接口测试工具,而Postman是业界有名的接口测试工具,自然接口测试就用它了. 坑 已经有一段时间没启动Postman了,突然发现启动一直卡在修复界面,重启也不 ...

  6. Qt在linux下实现程序编译后版本号自增的脚本

    #! /bin/bash rm -rf temp.cpp num=0 while read line do if [ $num -eq 3 ];then array=(`echo $line | tr ...

  7. 【Amadeus原创】GFS 安装使用

    准备环境: 一.修改每台主机的host文件,在/etc/hosts下添加内容: 172.62.21.44 gfs1 172.62.21.43 gfs2 172.62.21.37 gfs3 二.分别安装 ...

  8. .net core 文本比对的一个诡异设计

    9-11 发现的,过久了都忘了,记一下 string s = Encoding.ASCII.GetString(new byte[] { 0x57, 00, 0x49, 00, 0x4e, 00, 0 ...

  9. HttpClientManager

    HttpClientManger package com.gateway.http.client; import com.fasterxml.jackson.core.type.TypeReferen ...

  10. Qt通用方法及类库10

    函数名 //获取保存的文件 static QString getSaveName(const QString &filter, QString defaultDir = QCoreApplic ...