不能,mysql 8.0 的 instant 算法仅支持特定条件下的 add column 操作,不支持添加索引;建索引必须使用 algorithm=inplace + lock=none,instant 对其完全无效。

不能。 MySQL 8.0 的 INSTANT 算法不支持添加索引,只支持特定条件下的 ADD COLUMN 操作。
INSTANT 算法根本不管索引的事
很多人看到 “Instant DDL” 就以为所有 DDL 都能秒级,这是最常见误解。MySQL 8.0 的 INSTANT 是专为列添加设计的元数据级变更:它不写数据页、不碰聚簇索引、更不会触碰任何二级索引结构。而建索引(CREATE INDEX 或 ALTER TABLE ... ADD INDEX)本质是扫描表、排序键值、构建 B+ 树——这个过程必须读数据、分配页、写磁盘,INSTANT 完全无法绕过。
你查 INFORMATION_SCHEMA.INNODB_TABLES 或开 performance_schema 捕获 DDL 事件,永远找不到 instant 相关的索引操作痕迹。
加索引该用什么算法?ALGORITHM=INPLACE + LOCK=NONE
真正用于在线建索引的是 INPLACE 算法(MySQL 5.6 起支持),配合 LOCK=NONE 可实现大部分时间无锁。但要注意:
- 它仍需遍历聚簇索引(全表扫描),对千万级以上表可能耗时数分钟到数十分钟
- 期间允许并发 DML,但会在开始和结束阶段短暂加 MDL 锁(通常毫秒级)
- 若指定
ALGORITHM=INSTANT建索引,MySQL 直接报错:ERROR 1845 (0A000): ALGORITHM=INSTANT is not supported for this operation - 正确写法是:
ALTER TABLE t ADD INDEX idx_x (x), ALGORITHM=INPLACE, LOCK=NONE;
为什么 INSTANT 加完字段后建索引反而更快?
虽然 INSTANT 本身不加速建索引,但它把“加字段”和“建索引”解耦了:
- 先用
ALTER TABLE t ADD COLUMN x INT NULL, ALGORITHM=INSTANT;—— 耗时 - 再立即执行
ALTER TABLE t ADD INDEX idx_x (x), ALGORITHM=INPLACE, LOCK=NONE;—— 此时只需扫描新列x的值,不用等字段加完再协调业务窗口 - 避免了旧方式下“加字段几小时 → 建索引又几小时”的长链阻塞,整体风险大幅降低
注意:这个“更快”是指流程调度更快,不是单条建索引语句变快。
容易被忽略的关键点
真正影响建索引速度的,从来不是算法名,而是底层资源配置:
-
sort_buffer_size太小会导致卡在Sorting for table状态;千万行建议设为8388608(8MB)并用SET SESSION临时调整 -
innodb_buffer_pool_size不足会引发大量物理读,拖慢全表扫描 - 临时文件目录(
tmpdir)所在磁盘 I/O 瓶颈,比算法选择影响更大 - MySQL 8.0.27+ 支持
innodb_ddl_threads > 1并行构建二级索引,但默认是 1,必须显式开启才生效
别在 ALGORITHM=INSTANT 上浪费调试时间——它对索引无效,真要提速,盯紧 sort_buffer_size 和磁盘 IO。











