跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

mysql如何给已有数据表添加索引_使用CREATE INDEX提升查询速度

MySQL建索引需严格校验语法、字段与表名;优先用ALTER TABLE ADD INDEX;复合索引顺序须匹配查询条件;避免冗余索引;大表操作选低峰期;唯一索引承载约束语义;建索引后需ANALYZE TABLE更新统计信息。 CREATE INDEX 语法写错会直接报错,不是静默失败 MySQL 对
CREATE INDEX
的语法很敏感,尤其字段名、表名、索引类型稍有拼写或大小写不一致(在区分大小写的文件系统上),就会报
ERROR 1146 (42S02): Table doesn't exist
或
ERROR 1054 (42S22): Unknown column
。别急着怀疑权限,先核对三件事:
SHOW TABLES
确认表名完全匹配(含数据库前缀,如
mydb.users
)
DESCRIBE table_name
或
SHOW COLUMNS FROM table_name
看字段名是否带反引号、是否真存在 单列索引不用写
USING BTREE
,但复合索引里如果漏了括号,比如写成
CREATE INDEX idx ON t a,b
(缺
(a,b)
),会报语法错误 WHERE 条件里用不到的字段加索引纯属浪费 索引不是越多越好。比如表有
user_id
、
status
、
created_at
三个字段,但所有查询都是
WHERE status = ?
,那给
created_at
单独建索引几乎没用。真正该做的是: 用
EXPLAIN SELECT ...
看
key
列是否命中现有索引 复合索引顺序很重要:
WHERE status = ? AND created_at > ?
应建
INDEX(status, created_at)
,反过来则可能失效 如果经常
ORDER BY created_at
且带
LIMIT
,把
created_at
放复合索引末尾能避免 filesort ALTER TABLE ADD INDEX 比 CREATE INDEX 更常用,但锁表风险更高 虽然
CREATE INDEX idx ON t(col)
和
ALTER TABLE t ADD INDEX idx(col)
效果一样,但实际运维中更倾向后者,因为它是 DDL 标准写法,工具链(如 pt-online-schema-change)也默认识别它。不过要注意: MySQL(Linux) MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。 下载 MySQL 5.6+ 支持
ALGORITHM=INPLACE
,但加二级索引仍需短暂锁表;5.7+ 对普通 B-tree 索引支持真正的 online DDL,前提是没指定
LOCK=SHARED
或
LOCK=EXCLUSIVE
大表加索引务必在低峰期操作,否则
SELECT
可能被阻塞几秒到几分钟,取决于数据量和磁盘 I/O 不要在从库上直接建索引——主从复制本身不传索引变更,从库索引需手动同步,否则
SHOW CREATE TABLE
结果不一致 唯一索引和主键索引不能简单互换 有人看到
email
字段要查得快,顺手加个
UNIQUE INDEX
,结果插入重复值时程序直接抛
Duplicate entry 'x@y.z' for key 'idx_email'
。这不是性能问题,是语义问题:
UNIQUE INDEX
是约束 + 索引,会拒绝重复值;
INDEX
只加速查询,不拦数据 主键(
PRIMARY KEY
)自动是唯一且非空的,还隐式作为聚簇索引;普通唯一索引是二级索引,回表成本略高 如果业务本就要求 email 唯一,应该在建表时定义
email VARCHAR(255) UNIQUE
,而不是事后补索引——DDL 更清晰,应用层错误也更明确 最常被忽略的一点:索引生效依赖统计信息,而
ANALYZE TABLE
不会自动触发。表数据批量导入后,即使加了索引,优化器也可能因过时的行数估算而选错执行计划。别只盯着建索引,记得跑一次
ANALYZE TABLE your_table
。

相关文章