文章目录
- 1. 数据存储方式
- 2. 索引结构
- 3. 查询效率
- 4. 索引数量
- 5. 适用场景
- 6. 示例说明
- 7. 总结
在MySQL中,聚集索引和非聚集索引(也称二级索引)的区别主要体现在数据存储方式、索引结构和查询效率等方面。以下是详细对比:
1. 数据存储方式
-
聚集索引
数据行的物理存储顺序与索引顺序完全一致。
每个表只能有一个聚集索引,通常是主键。若未定义主键,InnoDB会隐式创建一个隐藏的ROW_ID
作为聚集索引。 -
非聚集索引
索引顺序与数据行的物理存储顺序无关。
叶子节点存储的是主键值(InnoDB)或数据行的物理地址(MyISAM),而非数据本身。
2. 索引结构
-
聚集索引
B+树的叶子节点直接包含完整的数据行,因此通过聚集索引查询时可直接获取数据,无需额外查找。 -
非聚集索引
B+树的叶子节点存储主键值(InnoDB)或指向数据行的指针(MyISAM)。查询时可能需要二次查找(回表),即通过主键值到聚集索引中获取完整数据行。
3. 查询效率
-
聚集索引
- 优点:范围查询(如
BETWEEN
、ORDER BY
)效率高,因为数据物理连续。 - 缺点:插入和更新可能引发页分裂,影响性能。
- 优点:范围查询(如
-
非聚集索引
- 优点:适合高频的等值查询(如
WHERE column = value
),且支持覆盖索引(查询字段全部在索引中时无需回表)。 - 缺点:回表操作可能导致额外I/O开销。
- 优点:适合高频的等值查询(如
4. 索引数量
-
聚集索引
每个表仅允许一个。 -
非聚集索引
每个表可创建多个(最多64个)。
5. 适用场景
-
聚集索引
适合主键查询、范围查询或需要频繁排序的场景。 -
非聚集索引
适合优化特定条件的查询(如WHERE
、JOIN
)或需要覆盖索引的场景。
6. 示例说明
假设有一个用户表users
,结构如下:
CREATE TABLE users (id INT PRIMARY KEY,username VARCHAR(50),email VARCHAR(50),INDEX idx_username (username)
) ENGINE=InnoDB;
- 聚集索引:
id
字段,数据按id
顺序存储。 - 非聚集索引:
idx_username
索引,叶子节点存储username
和对应的id
值。- 查询
SELECT * FROM users WHERE username = 'Alice'
时:- 通过
idx_username
找到username='Alice'
对应的id
。 - 通过
id
到聚集索引中获取完整数据行(回表)。
- 通过
- 查询
7. 总结
特性 | 聚集索引 | 非聚集索引 |
---|---|---|
数据存储 | 数据按索引顺序物理存储 | 数据独立存储,索引仅存储指针或主键 |
数量 | 每表一个 | 每表多个 |
查询效率 | 范围查询高效,直接获取数据 | 可能需回表,覆盖索引时高效 |
典型应用 | 主键、范围查询、排序 | 高频条件查询、覆盖索引优化 |
理解两者的区别有助于根据实际场景设计高效的索引策略。