【MySQL】 索引特性详解

索引是数据库优化中最重要的部分之一。它能显著提高数据查询效率,却也带来一定的写入成本。本文将从磁盘结构、Page机制、索引原理、索引类型以及索引操作五个方面全面剖析 MySQL 索引的特性与原理。


一、为什么需要索引?

在没有索引的情况下,MySQL 查询只能通过全表扫描来定位数据。当数据量达到数百万甚至上千万级时,查询性能会极大下降。

例如,若表中有 800 万条记录,执行以下查询:

SELECT * FROM EMP WHERE empno = 998877;

如果没有索引,查询可能耗时 4.93 秒,而加上索引后,仅需毫秒级。

索引的作用是 加快检索速度,但同时会 降低写操作性能。因为每次插入、更新或删除数据时,索引结构也要同步维护。


二、磁盘与存储的基础

2.1 磁盘的物理结构

MySQL 中的数据最终存储在磁盘的盘片中。每个盘片被划分为多个扇区(Sector),默认大小为 512字节。磁盘的基本结构由以下部分组成:

  • 柱面 (Cylinder):由多个磁道组成
  • 磁道 (Track):每个盘面的同心圆
  • 扇区 (Sector):磁道的最小存储单元

磁盘通过机械运动完成寻址,随机访问的效率明显低于 连续访问

2.2 磁盘访问效率

系统直接以 512 字节为单位进行 IO 会造成频繁磁盘访问,因此操作系统通常以 4KB 为基本块单位。而 MySQL 的 InnoDB 存储引擎则将交互单位设为 16KB Page,用以减少 IO 次数,提高效率。


三、MySQL 与磁盘交互的基本单位 —— Page

3.1 Page 的作用

MySQL 将数据文件按 Page(页) 存储在磁盘中,InnoDB 默认 Page 大小为 16KB。每个 Page 存放多条记录。

当 MySQL 需要访问数据时,会将 Page 整体加载到内存中的 Buffer Pool,从而减少频繁的磁盘 IO。

SHOW GLOBAL STATUS LIKE 'innodb_page_size';

返回结果:

| Innodb_page_size | 16384 |   -- 16*1024=16384

3.2 Page 的优势

例如要查找 id = 2 的记录:

  • 若一次只加载一条记录,需要多次 IO;
  • 若所有记录在一个 Page 中,只需一次 IO。

因此,Page 机制大大降低了磁盘访问次数。


四、索引的底层实现原理

4.1 为什么要排序?

MySQL 在存储数据时,会自动按照主键排序。这种有序存储是构建高效索引结构的前提。

通过排序,MySQL 可以更高效地引入“目录页”机制,使得数据定位不再依赖线性遍历。

4.2 页目录机制

Page 内部通过一个目录来快速定位数据。类似书籍的目录页,目录信息占用少量空间,却能大幅减少查找次数。

  • 页内目录:定位行记录;
  • 页间目录:定位页位置。

4.3 B+ 树结构的形成

随着数据量增加,单个 Page 不足以存储所有数据。此时,MySQL 会在 Page 之上建立“目录页”,形成 多层索引结构

这便是 B+ 树 —— MySQL InnoDB 索引的核心数据结构。

B+ 树特性:
  • 仅叶子节点存储数据;
  • 中间节点只存储键值与指针;
  • 所有叶子节点相连,支持范围查询;
  • 树高低意味着磁盘 IO 次数少,效率高。

五、B+ 树与其他数据结构对比

数据结构特点是否适合做索引
链表插入删除快,查询慢
二叉树结构简单,可能退化
红黑树平衡性好,但层数高⚠️
Hash表精确匹配快,不支持范围查找⚠️
B+树有序、支持范围查找、层级低

B+ 树的层高一般为 3~4 层,即使上千万数据,也能在几次磁盘访问内定位目标记录。


六、聚簇索引与非聚簇索引

6.1 聚簇索引(Clustered Index)

InnoDB 存储引擎中,主键索引与数据存储在同一结构中,称为 聚簇索引。主键索引叶节点存放完整行记录。

CREATE TABLE user (
  id INT PRIMARY KEY,
  name VARCHAR(20)
) ENGINE=InnoDB;

在文件系统中,表对应的 .ibd 文件同时保存索引与数据。

6.2 非聚簇索引(Non-Clustered Index)

MyISAM 引擎的索引与数据分离。索引叶节点存储的是数据记录的 地址,称为 非聚簇索引

CREATE TABLE user (
  id INT PRIMARY KEY,
  name VARCHAR(20)
) ENGINE=MyISAM;

查询过程:

  1. 通过索引定位记录地址;
  2. 再次访问数据文件读取数据(两次 IO)。

七、索引操作与语法

7.1 创建主键索引

-- 在字段定义中添加主键
CREATE TABLE user1(id INT PRIMARY KEY, name VARCHAR(30));

-- 在表定义中指定主键
CREATE TABLE user2(id INT, name VARCHAR(30), PRIMARY KEY(id));

-- 表创建后添加主键
ALTER TABLE user3 ADD PRIMARY KEY(id);

7.2 创建唯一索引

-- 创建表时指定唯一约束
CREATE TABLE user4(id INT PRIMARY KEY, name VARCHAR(30) UNIQUE);

-- 表后添加唯一索引
ALTER TABLE user5 ADD UNIQUE(name);

7.3 创建普通索引

CREATE INDEX idx_name ON user(name);
ALTER TABLE user ADD INDEX(name);

7.4 创建全文索引(MyISAM 专用)

CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200),
    body TEXT,
    FULLTEXT (title, body)
) ENGINE=MyISAM;

使用全文匹配:

SELECT * FROM articles WHERE MATCH(title, body) AGAINST('database');

7.5 查询索引

SHOW KEYS FROM table_name;
SHOW INDEX FROM table_name;
DESC table_name;

7.6 删除索引

ALTER TABLE table_name DROP PRIMARY KEY;
ALTER TABLE table_name DROP INDEX idx_name;
DROP INDEX idx_name ON table_name;

八、索引优化与原则

1. 创建索引的建议

  • 频繁出现在 WHEREORDER BY 的字段应创建索引;
  • 唯一性强的字段优先考虑;
  • 更新频繁的字段不建议建立索引;
  • 不参与查询条件的字段无需创建索引。

2. 其他优化概念

  • 复合索引:多个字段联合创建索引;
  • 最左前缀匹配:索引生效顺序与字段排列一致;
  • 索引覆盖:查询列全部包含在索引中,无需回表。

九、总结

  • 索引是数据库性能优化的核心;
  • Page 机制有效减少磁盘 IO;
  • InnoDB 采用 B+ 树管理索引;
  • 聚簇索引与非聚簇索引在数据存储上存在根本差异;
  • 合理设计与使用索引能极大提升查询效率。

“索引不是越多越好,而是用对地方,事半功倍。”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值