MySQL索引的完整教程(创建、查看、修改、删除与日常管理)
一、索引基础说明
InnoDB 支持:主键索引、普通索引、唯一索引、联合复合索引、前缀索引、全文索引;
索引核心作用:加速 WHERE / JOIN / ORDER BY / GROUP BY 查询;
代价:插入、更新、删除时需要维护 B+ 树,索引越多写入性能越差。
二、创建索引三种方式
方式1:建表时直接定义索引(推荐规范写法)
CREATE TABLE `openapi_apilog` ( id BIGINT AUTO_INCREMENT COMMENT '主键', user_id VARCHAR(32) NOT NULL, date DATE NOT NULL, path VARCHAR(500) NOT NULL, login_ip VARCHAR(50), price DECIMAL(10,2), creat_time DATETIME, -- 主键索引 PRIMARY KEY (`id`), -- 普通联合索引 INDEX idx_user_date (user_id, date), -- 唯一索引 UNIQUE INDEX uk_path_uid (path, user_id), -- 字符串前缀索引(path只截取前40字符建索引,节省空间) INDEX idx_path_prefix (path(40)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT '接口日志表';
各类索引在建表时关键字区分
PRIMARY KEY:主键索引,一张表只能一个,非空且唯一;INDEX / KEY:普通索引,无唯一性限制;UNIQUE INDEX:唯一索引,字段值不能重复,允许一条 NULL;path(N):前缀索引,长字符串专用。
方式2:已有表追加创建索引(线上最常用)
语法通用:
CREATE [UNIQUE] INDEX 索引名 ON 表名(字段1, 字段2...);
1)普通单列索引
CREATE INDEX idx_user_id ON openapi_apilog(user_id);
2)联合复合索引(多字段组合)
CREATE INDEX idx_user_date_path ON openapi_apilog(user_id, date, path);
3)唯一索引
CREATE UNIQUE INDEX uk_verify_id ON openapi_apilog(verify_idf_id);
4)前缀索引(长URL、地址字段)
CREATE INDEX idx_path_prefix ON openapi_apilog(path(40));
5)覆盖索引(查询字段全部放进索引,消除回表)
CREATE INDEX idx_cover ON openapi_apilog(user_id, date, path, login_ip, price, creat_time);
方式3:ALTER TABLE 语句创建索引
底层和 CREATE INDEX 效果一致,兼容老版本:
-- 普通索引 ALTER TABLE openapi_apilog ADD INDEX idx_date (date); -- 唯一索引 ALTER TABLE openapi_apilog ADD UNIQUE INDEX uk_ip (login_ip); -- 主键索引(表无主键时添加) ALTER TABLE openapi_apilog ADD PRIMARY KEY (`id`);
三、查看索引(管理必备命令)
1. SHOW INDEX FROM 表名(最常用)
SHOW INDEX FROM openapi_apilog;
关键字段解读:
Key_name:索引名称;Seq_in_index:联合索引内字段顺序;Column_name:索引字段;Non_unique:0=唯一索引/主键,1=普通索引;Cardinality:基数,代表区分度,数值越大索引效率越高。
2. DESCRIBE / DESC 查看表结构附带索引
DESC openapi_apilog;
3. 查询系统表,查看全库索引
SELECT TABLE_NAME, INDEX_NAME, COLUMN_NAME, NON_UNIQUE FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = DATABASE() ORDER BY TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX;
4. 查询从未使用过的闲置索引(清理冗余用)
SELECT * FROM sys.schema_unused_indexes;
5. EXPLAIN 验证索引是否生效
EXPLAIN SELECT login_ip,price FROM openapi_apilog WHERE user_id='10001' AND date='2026-07-02';
type = ALL:全表扫描,未走索引;key列有索引名:成功命中索引;- Extra 出现
Using index:命中覆盖索引,无回表。
四、修改索引
MySQL 不支持直接修改索引字段,只能先删除旧索引,再重建新索引。
示例:原有 idx_user_date,需要改成 user_id + date + creat_time
-- 1. 删除旧索引 DROP INDEX idx_user_date ON openapi_apilog; -- 2. 创建新索引 CREATE INDEX idx_user_date_time ON openapi_apilog(user_id, date, creat_time);
五、删除索引
方式1:DROP INDEX(推荐)
DROP INDEX idx_path_prefix ON openapi_apilog;
方式2:ALTER TABLE 删除索引
ALTER TABLE openapi_apilog DROP INDEX idx_user_date_path;
删除主键特殊写法
ALTER TABLE openapi_apilog DROP PRIMARY KEY;
注意:如果主键是自增字段,删除前必须先去掉
AUTO_INCREMENT。
六、索引日常管理规范与运维操作
1. 建索引线上注意事项
1)大表千万不要直接在线执行 CREATE INDEX
500万行以上表新建索引会锁表阻塞读写,解决方案:
- MySQL5.6+ 支持在线无锁创建:
ALTER TABLE ... ADD INDEX LOCK=NONE; - 使用 pt-online-schema-change 工具在线加索引,避免锁表;
- 业务低峰期凌晨执行。
2. 清理冗余索引规则
已有联合索引 (a,b,c),无需单独创建 (a)、(a,b) 单列索引,联合索引天然支持最左前缀查询,多余索引只会加重写入压力。
3. 索引碎片整理
大量 DELETE / UPDATE 会产生索引碎片,降低查询效率:
OPTIMIZE TABLE openapi_apilog;
InnoDB 会重建表和索引,释放碎片空间。
4. 索引数量控制
单表索引建议不超过 5 个,INSERT / UPDATE / DELETE 时每条索引都要同步更新。
5. 区分度判断(建索引前校验)
-- 区分度越接近1,索引效果越好 SELECT COUNT(DISTINCT user_id)/COUNT(*) FROM openapi_apilog;
区分度低于0.1(如status 0/1状态)不建议单独建索引。
七、常见索引管理踩坑
- 索引字段加函数、后置模糊匹配
%xxx、隐式类型转换 → 索引失效; - 联合索引顺序错误,范围字段放前面,后面字段无法利用索引;
- 长字符串不加前缀索引,索引文件体积过大,缓存命中率低;
- 线上大表直接创建索引,长时间锁表引发业务超时;
- 大量冗余索引,写入接口TPS持续下跌。
八、完整操作流程总结
- 建表阶段:按需定义主键、联合索引;
- 后期新增:
CREATE INDEX/ALTER TABLE ADD INDEX; - 查看校验:
SHOW INDEX+EXPLAIN确认是否命中; - 调整索引:先 DROP 再 CREATE;
- 清理维护:删除无用索引、定期 OPTIMIZE 整理碎片;
- 线上大表操作:使用在线DDL工具避免锁表。
以上就是MySQL索引的完整教程(创建、查看、修改、删除与日常管理)的详细内容,更多关于MySQL索引完整教程的资料请关注脚本之家其它相关文章!
相关文章
使用shardingsphere实现mysql数据库分片方式
本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置方法,适用于大数据场景下的数据库扩展2025-08-08


最新评论