外观
MySQL 索引的定义
⭐ 题目日期:
字节 - 2024/12/10
📝 题解:
MySQL 索引是数据库中用于 加速数据检索 的一种数据结构,通过建立数据的特定映射关系,减少查询时需要扫描的数据量。以下是 MySQL 索引的核心定义、类型、实现机制及使用建议:
一、索引的核心定义
- 本质: 索引是一种 有序的数据结构(如 B+树、哈希表),存储表中某列(或列组合)的值及其对应数据的物理地址(如主键值或行指针)。
- 作用:
- 加速查询:避免全表扫描,快速定位目标数据。
- 约束数据:唯一索引(Unique Index)保证列值的唯一性。
- 代价:
- 存储空间:索引需要额外存储。
- 维护成本:数据增删改时需同步更新索引。
二、索引的类型
1. 按数据结构分类
索引类型 | 数据结构 | 特点 |
---|---|---|
B+Tree 索引 | B+树 | MySQL 默认索引,支持全值匹配、范围查询、排序和分组。适合高基数(唯一值多)字段。 |
哈希索引 | 哈希表 | 仅支持等值查询(如 = 、IN ),不支持排序和范围查询。适合内存表(MEMORY引擎)。 |
全文索引 | 倒排索引 | 用于文本内容的全文搜索(MATCH ... AGAINST ),支持关键词匹配。 |
空间索引 | R-Tree | 支持地理空间数据类型(如 GEOMETRY ),用于范围查询和空间关系判断。 |
2. 按功能分类
索引类型 | 特点 |
---|---|
主键索引 | 唯一标识每行数据,不允许 NULL 值,一张表只能有一个。 |
唯一索引 | 确保列值唯一,允许 NULL 值(但只能有一个 NULL )。 |
普通索引 | 无唯一性约束,仅加速查询。 |
联合索引 | 基于多列组合的索引,遵循 最左前缀原则。 |
覆盖索引 | 索引包含查询所需的所有字段,无需回表查询数据行。 |
三、B+Tree 索引的底层实现
1. B+树结构
- 非叶子节点:存储键值(索引列值)和子节点指针,不存储数据。
- 叶子节点:存储键值和数据指针(主键值或行数据地址),叶子节点通过指针形成有序链表。
- 平衡性:所有叶子节点位于同一层,保证查询效率稳定(时间复杂度
O(log N)
)。
2. 优势
- 范围查询高效:叶子节点链表支持快速范围扫描(如
WHERE id > 100
)。 - 减少磁盘 I/O:树的高度低,减少磁盘访问次数(节点大小通常与磁盘页对齐)。
- 排序优化:索引本身有序,避免
ORDER BY
的额外排序开销。
四、索引的创建与管理
1. 创建索引
-- 创建普通索引
CREATE INDEX idx_name ON table_name (column1, column2);
-- 创建唯一索引
CREATE UNIQUE INDEX idx_unique_email ON users (email);
-- 创建主键索引(通常在建表时指定)
ALTER TABLE table_name ADD PRIMARY KEY (id);
2. 查看索引
SHOW INDEX FROM table_name;
3. 删除索引
DROP INDEX idx_name ON table_name;
五、索引的使用原则
1. 适合创建索引的场景
- 高频查询字段:如
WHERE
、JOIN
、ORDER BY
、GROUP BY
涉及的列。 - 高区分度列:列值的唯一性高(如用户ID、手机号)。
- 联合索引优化:根据查询条件组合多列,注意最左前缀原则。
2. 避免无效索引
- 低区分度列:如性别(只有男/女)不适合单独建索引。
- 频繁更新的列:维护索引的代价可能超过查询收益。
- 过长的字段:如
TEXT
类型,应使用前缀索引(INDEX (column(10))
)。
3. 索引失效的常见原因
- 违反最左前缀原则:联合索引未从最左列开始使用。
- 对索引列运算或函数:如
WHERE YEAR(create_time) = 2023
。 - 隐式类型转换:如字符串列使用数字查询
WHERE id = '100'
。 - OR 连接非索引列:如
WHERE a=1 OR b=2
(若b
无索引,全表扫描)。
六、示例与最佳实践
1. 联合索引的最左前缀原则
索引定义:
INDEX (a, b, c)
。有效查询:
WHERE a = 1; WHERE a = 1 AND b = 2; WHERE a = 1 AND b = 2 AND c = 3; WHERE a = 1 ORDER BY b, c;
无效查询:
WHERE b = 2; -- 未使用 a WHERE a = 1 AND c = 3; -- 跳过 b
2. 覆盖索引优化
- 查询:
SELECT name FROM users WHERE age = 25;
- 索引:
CREATE INDEX idx_age_name ON users (age, name);
- 索引包含所有查询字段,无需回表。
七、总结
MySQL 索引通过 B+树 等数据结构加速数据检索,核心要点包括:
- 索引类型:B+Tree(默认)、哈希、全文、空间索引。
- 使用原则:高频查询字段、高区分度列、避免冗余索引。
- 优化方向:覆盖索引、联合索引最左前缀、减少索引失效场景。
合理使用索引可显著提升查询性能,但需平衡存储成本与维护开销。