CREATE INDEX 的基本写法和必要参数
MySQL 中
CREATE INDEX不能在主键或唯一约束字段上重复创建同名索引,且必须指定索引名、表名和至少一个列。最简可用形式是:
CREATE INDEX idx_name ON table_name (column_name);
idx_name是你自定义的索引名,建议带前缀如
idx_或
uk_(唯一索引)便于识别
table_name必须存在且当前用户有
INDEX权限
column_name可以是单列,也可以是多列(用逗号分隔),顺序影响联合索引的最左匹配效果 不支持在临时表上创建普通索引(MySQL 8.0.13+ 允许对临时表建索引,但行为受限)
什么时候必须用 ALTER TABLE 替代 CREATE INDEX
如果要创建的是主键索引、唯一索引、全文索引或空间索引,
CREATE INDEX无法完成——这些类型必须通过
ALTER TABLE添加。 主键:
ALTER TABLE t ADD PRIMARY KEY (id);唯一索引:
ALTER TABLE t ADD UNIQUE uk_email (email);全文索引(仅 MyISAM / InnoDB):
ALTER TABLE t ADD FULLTEXT ft_content (content);空间索引(仅 MyISAM):
ALTER TABLE t ADD SPATIAL sp_geom (geom);
直接对已有列执行
CREATE INDEX idx_email ON t (email)不会自动变成唯一索引,即使该列本身无重复值。
常见错误:Duplicate column name 和 Can't write; duplicate key
这两个报错常被混淆,但原因完全不同:
Duplicate column name 'xxx':说明你在
(...)里写了重复列名,比如
(a, a)或
(a, b, a)
Can't write; duplicate key in table:通常出现在创建唯一索引时,表中已有违反唯一性的数据(例如两行
email = 'a@b.com') 还有一种隐性问题:对
TEXT或
BLOB列建索引必须指定前缀长度,否则报错
BLOB/TEXT column 'xxx' used in key specification without a key length,应写成
(content(255))
性能与在线 DDL 的实际影响
MySQL 5.6+ 对大多数
CREATE INDEX操作支持在线 DDL(in-place),但仍有例外: InnoDB 表默认使用
ALGORITHM=INPLACE,不阻塞 DML(INSERT/UPDATE/DELETE),但会加元数据锁(MDL),长事务可能卡住建索引 如果显式指定
ALGORITHM=COPY,会锁表并复制整张表,大表慎用 建索引过程会占用磁盘空间(临时排序文件 + 新索引页),尤其对几十 GB 以上的表,需预留足够
tmpdir空间 索引列选择要克制:不是越多越好,冗余索引(如已有
(a,b),再建
(a))会被优化器忽略,还拖慢写入
真正容易被忽略的是:建完索引后,优化器不会立刻更新统计信息,有时需要手动执行
ANALYZE TABLE table_name;才能触发执行计划重编译。
