MySQL 索引的相关知识

一、索引的作用

1. 核心作用

  • 加速查询:这是索引最主要的作用。没有索引时,MySQL 需要全表扫描(逐行检查),数据量大时非常慢;有索引时,可以直接定位到数据

  • 加速排序ORDER BY 可以利用索引避免额外的排序操作

  • 加速分组GROUP BY 可以利用索引提高效率

  • 加速去重DISTINCT 可以利用索引

  • 维护唯一性:唯一索引可以保证数据的唯一性约束

2. 代价(副作用)

  • 占用额外存储空间:索引本身也是数据结构,需要磁盘空间

  • 降低写操作速度 :每次 INSERTUPDATEDELETE 时,都需要同时维护索引结构

  • 增加内存消耗:查询时索引需要加载到内存

二、索引的数据结构

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行)            | 不需要索引,全表扫描更快 |
相关推荐
神明9311 小时前
如何处理ORA-01152报错_恢复未完成导致的数据文件仍需介质恢复
jvm·数据库·python
许长安1 小时前
Redis 跳表实现详解
数据库·c++·经验分享·redis·笔记·缓存
m0_596749091 小时前
mysql如何导出特定条件的查询数据_使用mysqldump加where参数
jvm·数据库·python
还是鼠鼠2 小时前
AI掘金头条新闻系统 (Toutiao News)-获取新闻分类
后端·python·mysql·fastapi·web
赢乐2 小时前
大模型学习笔记:LangChain核心组件-记忆(memory)
数据库·langchain·长短时记忆网络·长期记忆·短期记忆·智能体agent·记忆(memory)
jieyucx2 小时前
Go语言通透教程:结构体定义与方法
服务器·数据库·golang·结构体
m0_690825822 小时前
c++ RAII机制详解 c++如何利用RAII管理资源
jvm·数据库·python
无小道2 小时前
Mysql——操作篇
mysql·操作··
JunLa2 小时前
L angGraph vs 链式调用
java·网络·数据库