INSTANT ADD COLUMN 不能与 ADD INDEX 同时执行,因为 ADD INDEX 会强制整个 ALTER TABLE 降级为 INPLACE 或 COPY 模式;必须分两步:先 INSTANT 加列,再 INPLACE 建索引。

不支持。 INSTANT ADD COLUMN 仅作用于纯列定义变更,加索引(ADD INDEX)会直接导致整个 ALTER TABLE 语句 fallback 到 INPLACE 或 COPY 模式,INSTANT 算法完全失效。
为什么 INSTANT ADD COLUMN 不能和 ADD INDEX 同时执行
MySQL 的 ALGORITHM=INSTANT 是原子性策略:只要语句中包含任何不支持 instant 的子操作(如建索引、改列类型、重命名等),整个 DDL 就会被拒绝或静默降级。这不是语法限制,而是引擎层的硬性约束。
-
ADD INDEX必须遍历聚簇索引 B+ 树来提取索引键值,这与 INSTANT “零行扫描”的设计目标根本冲突 - 即使新列本身满足 INSTANT 条件(比如末尾加
status TINYINT DEFAULT 0),只要语句里带了ADD INDEX idx_status (status),就会触发ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported - MySQL 不会拆解语句、分段执行;它只看整条
ALTER TABLE是否 100% 符合 instant 规则
如何正确给新列加索引
必须严格分两步:先加列(INSTANT),再建索引(INPLACE)。这两步之间可以有任意时间间隔,互不影响。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- ✅ 第一步(毫秒级):
ALTER TABLE t ADD COLUMN status TINYINT DEFAULT 0, ALGORITHM=INSTANT; - ✅ 第二步(耗时取决于数据量):
ALTER TABLE t ADD INDEX idx_status (status), ALGORITHM=INPLACE; - ❌ 错误写法(哪怕只多一个逗号):
ALTER TABLE t ADD COLUMN x INT, ADD INDEX idx_x (x);—— 这会静默退化为INPLACE,且锁表时间显著增加
哪些情况会让 INSTANT 加列失败并间接影响索引计划
INSTANT 加列本身失败,会导致你无法用“先瞬时加列、再异步建索引”这个节奏,被迫走传统长耗时路径。常见踩坑点:
- 表使用了
ROW_FORMAT=COMPRESSED(查SELECT ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME = 'db/t'确认) - 表上存在
FULLTEXT索引(哪怕只是历史残留,DROP FULLTEXT INDEX后才能启用 INSTANT) - MySQL 版本是 8.0.12–8.0.27 且表没有显式主键(即隐式主键),此时 INSTANT 被禁用
- 云数据库环境未同步开启
loose_innodb_instant_ddl_enabled参数(主从需一致)
真正容易被忽略的是:INSTANT 只保“加列”这一步的瞬时性;后续建索引的耗时、锁表现、复制延迟,和 INSTANT 完全无关——它只负责把列名写进字典,不负责让索引变快。










