2. 索引:书的目录
索引(Index)是帮助 MySQL 高效获取数据的数据结构,本质是一套"排好序的快速查找结构",就像书的目录。
作用:① 大幅加速检索(避免全表扫描);② 降低磁盘 IO;③ 支持排序分组;④ 唯一索引保证不重复。
代价:① 占用存储空间;② 增删改时要同步维护索引,写入变慢;③ 索引多会碎片化。
/* 索引语法 创建索引 CREATE [UNIQUE|FULLTEXT] INDEX index_name ON table_name (index_col_name,...); */ -- 创建普通索引 CREATE INDEX index_sname ON student(sname); -- 创建唯一索引 CREATE UNIQUE INDEX uk_sno ON student(sno); -- 创建复合索引 CREATE INDEX idx_sname_sno ON student(sname, sno); -- 创建全文索引 CREATE FULLTEXT INDEX ft_sbirthplace ON student(sbirthplace); -- 查看索引 SHOW INDEX FROM table_name ; show index from student; -- 删除索引 DROP INDEX index_name ON table_name;
⚠️ 索引不是越多越好!写频繁的表(如日志)索引多了反而拖累性能。常作为查询条件、连接条件的字段才适合建索引。主键自带主键索引,无需再建。
📝 本节例题
以下例题均基于 教学实例 库(student / course / sc / teacher / grades / dept / emp),开始前先执行 USE 教学实例;。建议先自己写一遍,再展开答案对照。
例 1
给 student 表的姓名字段创建普通索引 idx_sname。
查看参考答案(可复制)
sql
CREATE INDEX idx_sname ON student(Sname);
-- 已存在时先删:DROP INDEX idx_sname ON student;💡 索引用得多、改得少的列才适合建;建太多会拖慢增删改。
例 2
给 sc 表创建联合索引 idx_sno_cno(学号, 课程号),并用 EXPLAIN 验证按学号查询时索引生效。
查看参考答案(可复制)
sql
CREATE INDEX idx_sno_cno ON sc(Sno, Cno);
EXPLAIN SELECT * FROM sc WHERE Sno = '001';💡 联合索引有最左前缀原则:查 Sno 能用上,只查 Cno 用不上。
例 3
给 emp 建联合索引 idx_dept_salary(部门, 薪资),分别用“部门”和“薪资”作条件执行 EXPLAIN 体会最左前缀原则,最后删除该索引。
查看参考答案(可复制)
sql
CREATE INDEX idx_dept_salary ON emp(dept_id, salary);
EXPLAIN SELECT * FROM emp WHERE dept_id = 1; -- 用得上索引
EXPLAIN SELECT * FROM emp WHERE salary > 10000; -- 用不上(跳过了最左列)
DROP INDEX idx_dept_salary ON emp;💡 复合索引 (a, b) 相当于同时有了 a 和 (a,b) 的索引,但单独查 b 时无效。