MySQL 8.0的ADD COLUMN“秒级”完成是因为INSTANT算法仅修改元数据、不重写数据;但需同时满足六项条件(唯一操作、末尾添加、字面量/NULL默认值、Dynamic行格式、无全文索引、InnoDB引擎),缺一则退化为INPLACE或COPY。

ALTER TABLE ... ADD COLUMN 在 MySQL 8.0 上“秒级”完成,不是因为磁盘或 CPU 变快了,而是它**跳过了数据重写**——只要满足条件,就只改元数据,不碰一行数据。MySQL 5.7 几乎总是重建整张表,哪怕加一个 TINYINT。
Instant Add Column 是什么,为什么 5.7 没有?
MySQL 8.0.12+ 引入了 INSTANT 算法,本质是“逻辑加列”:新列对旧数据行不做物理填充,首次读取时才按默认值动态补(lazy fill)。而 5.7 没有该机制,所有 ADD COLUMN 都必须走 ALGORITHM=COPY 或降级的 INPLACE,强制重写每一页聚簇索引。
哪些 ADD COLUMN 能真正走 INSTANT?必须全满足
缺一条就会退化为慢操作,常见误判点都在这里:
-
ADD COLUMN必须是语句中唯一操作(不能和DROP COLUMN、MODIFY COLUMN、RENAME COLUMN同时出现) - 新增列必须追加在末尾(不能用
FIRST,也不能用AFTER col_x指向中间位置) - 默认值只能是
NULL或字面量(如DEFAULT 'abc'、DEFAULT 42),DEFAULT NOW()或DEFAULT (id + 1)不行 - 表格式必须是
ROW_FORMAT=Dynamic或Compressed(Compact和Redundant不支持) - 表不能有任何
FULLTEXT索引(哪怕只建了一个,ADD COLUMN就强制COPY) - 引擎必须是
InnoDB(MyISAM、临时表完全不识别INSTANT)
为什么我加了个字段还是慢?常见退化场景
很多看似简单的操作已悄悄退化,且不会报错,只会变慢:
- 执行后查
SHOW CREATE TABLE tbl_name,输出里没出现ALGORITHM=INSTANT→ 没走 Instant(可能是 INPLACE 或 COPY) - 表上有
FULLTEXT索引 → 直接退化为COPY,哪怕只是加TINYINT NOT NULL DEFAULT 0 - 用了
pt-online-schema-change或gh-ost→ 工具不识别 Instant,一律走影子表,完全绕过优化 - MySQL 8.0.12 之前版本对
NOT NULL DEFAULT 'x'支持不完整,可能误判需填充旧数据而拒绝 Instant - 执行期间
information_schema.INNODB_METRICS中dml_rows_inserted计数暴涨 → 正在写新行,已退化
验证是否真走了 INSTANT 的最可靠方式
别信文档、别信版本号,只信三件事:
- 执行前确认:
SELECT @@innodb_file_format, @@innodb_file_per_table, @@row_format;(确保 Dynamic) - 执行后立刻查:
SHOW CREATE TABLE t;—— 必须看到ALGORITHM=INSTANT字样 - 对大表执行前后对比
SELECT COUNT(*) FROM t;耗时,INSTANT 下应无明显变化(COPY下会卡住几秒到几小时)
最容易被忽略的是全文索引和 FIRST 语法;一旦存在,Instant 就彻底失效,但 MySQL 不会警告你——它只是默默切回老路。


















