索引
索引加速数据检索——没有索引需要全表扫描,有索引可以快速定位目标行。
索引在表的一列或多列上创建,数据库引擎会维护一个排序的数据结构(通常是 B-Tree),让查询能快速定位目标行,避免全表扫描。索引会占用额外的磁盘空间,并且在 INSERT、UPDATE、DELETE 时需同步维护,所以不是越多越好——只在查询频繁的列(WHERE、JOIN、ORDER BY 涉及的列)上建索引。
MySQL 支持多种索引类型:普通索引(INDEX)仅加速查询;唯一索引(UNIQUE INDEX)加速查询 + 保证唯一性;全文索引(FULLTEXT)用于全文搜索;复合索引(多列组合)遵循最左前缀原则——查询条件必须包含最左边的列才能走索引。
什么场景需要它?当表的数据量达到万级以上时,索引带来的性能提升是数量级的。飞翔科技的员工表如果有百万条记录,按姓名查找员工若没索引就得扫描百万行;建个索引,可能只需几次 I/O 就找到了。在高并发系统中,合理的索引设计直接决定用户体验和系统吞吐量。
标准写法:
-- 创建普通索引
CREATE INDEX 索引名 ON 表名 (列名);
-- 创建唯一索引
CREATE UNIQUE INDEX 索引名 ON 表名 (列名);
-- 创建复合索引
CREATE INDEX 索引名 ON 表名 (列名1, 列名2);
-- 删除索引
DROP INDEX 索引名 ON 表名;
以飞翔科技为例。员工表上为常用查询列创建索引:
-- 为姓名建索引,加速按姓名搜索
CREATE INDEX idx_emp_name ON employees (emp_name);
-- 为部门代码 + 入职年份建复合索引
-- 加速"技术部 2018 年入职员工"这类查询
CREATE INDEX idx_dept_join ON employees (dept_code, join_year);
-- 查询技术部(dept_code=2)2018 年入职员工
-- 此查询会走 idx_dept_join 索引
SELECT emp_name, basic_salary
FROM employees
WHERE dept_code = 2 AND join_year = 2018;
-- 查看表的索引情况
SHOW INDEX FROM employees;
主键和 UNIQUE 约束会自动创建索引,所以 emp_id 和 email 已经自带索引了。idx_dept_join 这样的复合索引,能同时加速 WHERE dept_code=...、WHERE dept_code=... AND join_year=... 以及 ORDER BY dept_code, join_year 等多种查询。用 EXPLAIN 关键字可以查看查询是否真的走了索引,这是优化 SQL 性能的基本功。