一、索引的作用
1. 核心作用
-
加速查询:这是索引最主要的作用。没有索引时,MySQL 需要全表扫描(逐行检查),数据量大时非常慢;有索引时,可以直接定位到数据
-
加速排序 :
ORDER BY可以利用索引避免额外的排序操作 -
加速分组 :
GROUP BY可以利用索引提高效率 -
加速去重 :
DISTINCT可以利用索引 -
维护唯一性:唯一索引可以保证数据的唯一性约束
2. 代价(副作用)
-
占用额外存储空间:索引本身也是数据结构,需要磁盘空间
-
降低写操作速度 :每次
INSERT、UPDATE、DELETE时,都需要同时维护索引结构 -
增加内存消耗:查询时索引需要加载到内存
二、索引的数据结构
MySQL 主要使用 B+树 作为索引结构:
B+树特点:
- 所有数据都存储在叶子节点
- 叶子节点之间通过指针相连(方便范围查询)
- 非叶子节点只存储键值,不存储数据
- 树的高度很低(通常3-4层),查询效率高
三、索引类型

php
| 类型 | 说明 | 使用场景 |
| ----------------------- | --------------- | --------------------------- |
| **主键索引 (Primary Key)** | 唯一且非空,每张表只能有一个 | 表的主标识 |
| **唯一索引 (Unique)** | 值必须唯一,允许一个 NULL | 需要唯一约束的字段(如邮箱、手机号) |
| **普通索引 (Normal/Index)** | 无唯一约束 | 频繁查询的字段 |
| **全文索引 (Fulltext)** | 针对文本内容 | 大文本搜索(MySQL 5.6+ InnoDB 支持) |
| **组合索引 (Composite)** | 多个字段联合索引 | 多条件查询 |
四、索引设计原则与技巧
原则 1:为 WHERE 条件中的字段建索引
sql
-- 频繁这样查询
SELECT * FROM users WHERE age = 25;
-- 应该给 age 建索引
CREATE INDEX idx_age ON users(age);
原则 4:选择性高的字段更适合建索引
选择性 = 不重复值数量 / 总记录数
-
选择性越接近 1,索引效果越好
-
选择性很低的字段(如性别,只有男女两种值)不适合单独建索引
sql
-- 不好:选择性太低
CREATE INDEX idx_gender ON users(gender); -- 只有男/女,索引效果差
-- 好:选择性高
CREATE INDEX idx_email ON users(email); -- 几乎不重复
五、索引设计标准/规范建议
sql
| 索引类型 | 命名格式 | 示例 |
| ---- | ------------- | -------------------- |
| 主键 | `pk_表名` | `pk_users` |
| 唯一索引 | `uk_字段名` | `uk_email` |
| 普通索引 | `idx_字段名` | `idx_create_time` |
| 组合索引 | `idx_字段1_字段2` | `idx_user_id_status` |
设计检查清单
在设计索引时,问自己以下几个问题:
-
这个字段查询频率高吗? 低频查询不值得建索引
-
这个字段的选择性高吗? 低于 10% 的字段慎重考虑
-
这个字段会频繁更新吗? 频繁更新的字段建索引会增加维护成本
-
是否已经有类似的索引? 避免冗余
-
是否需要覆盖索引优化? 考虑查询的字段组合
-
索引数量是否过多? 单表不超过 5-7 个
总结

sql
| 场景 | 建议 |
| ---------------------- | ------------ |
| 主键 | 必须建,用自增整数 |
| 外键 | 建议建索引 |
| WHERE 条件字段 | 高频查询的建 |
| ORDER BY / GROUP BY 字段 | 考虑建索引 |
| 选择性低的字段 | 不单独建,可放组合索引中 |
| 频繁更新的字段 | 慎重建索引 |
| 小表(<<1000行) | 不需要索引,全表扫描更快 |
