目 录CONTENT

文章目录

【数据库】聚簇索引与非聚簇索引

EulerBlind
2025-11-06 / 0 评论 / 0 点赞 / 2 阅读 / 0 字

一、核心概念

聚簇索引(Clustered Index)

本质:数据行的物理存储顺序与索引键值的逻辑顺序相同,索引和数据存储在一起

形象比喻:像一本按拼音排序的字典,内容本身就是按拼音顺序存放的,找到索引位置就直接找到了内容。

非聚簇索引(Non-Clustered Index)

本质:索引的逻辑顺序与数据的物理存储顺序无关,索引和数据分开存储

形象比喻:像书的目录,目录指向内容的页码,需要先查目录再根据页码翻到具体内容。


二、存储结构对比

聚簇索引的存储结构

B+树结构:
         [10, 20, 30]
        /      |      \
   [5,8,10] [15,18,20] [25,28,30]
      ↓        ↓         ↓
   完整数据行 完整数据行  完整数据行
  • 叶子节点:直接存储完整的数据行
  • 查找效率:找到索引就找到数据,一次IO

非聚簇索引的存储结构

B+树结构:
         [10, 20, 30]
        /      |      \
   [5,8,10] [15,18,20] [25,28,30]
      ↓        ↓         ↓
   主键值    主键值     主键值
      ↓
   回表查询 → 聚簇索引 → 完整数据
  • 叶子节点:存储索引列的值 + 主键值(或行指针)
  • 查找效率:需要回表,两次IO操作

三、关键区别对比

维度聚簇索引非聚簇索引
数量限制一张表只能有一个一张表可以有多个
存储方式索引与数据在一起索引与数据分离
叶子节点存储完整数据行存储索引列值+主键值
查询性能直接获取数据,快需要回表,相对慢
插入性能可能导致页分裂,慢相对较快
数据顺序物理有序逻辑有序,物理无序
适用场景范围查询、排序精确查询、覆盖索引

四、MySQL中的实现

InnoDB引擎(必有聚簇索引)

  1. 有主键:主键就是聚簇索引
  2. 无主键但有唯一索引:第一个非空唯一索引作为聚簇索引
  3. 都没有:InnoDB自动创建隐藏的6字节ROWID作为聚簇索引
-- 示例表结构
CREATE TABLE users (
    id INT PRIMARY KEY,           -- 聚簇索引
    name VARCHAR(50),
    age INT,
    INDEX idx_name (name),        -- 非聚簇索引
    INDEX idx_age (age)           -- 非聚簇索引
);

MyISAM引擎(全是非聚簇索引)

  • 数据和索引完全分离
  • 主键索引和普通索引结构相同
  • 叶子节点存储的是数据文件的地址指针

五、性能影响实例

场景1:主键查询

SELECT * FROM users WHERE id = 100;
  • 聚簇索引:1次IO,直接命中
  • 非聚簇索引:需要通过其他索引回表

场景2:辅助索引查询

SELECT * FROM users WHERE name = 'Zhang';

执行过程:

  1. 在name的非聚簇索引中找到 'Zhang' → 得到主键值id=100
  2. 用id=100去聚簇索引中回表查询完整数据
  3. 两次IO操作

场景3:覆盖索引(避免回表)

SELECT id, name FROM users WHERE name = 'Zhang';
  • name索引的叶子节点包含:name值 + id值
  • 无需回表,1次IO,这就是覆盖索引优化

场景4:范围查询

SELECT * FROM users WHERE id BETWEEN 100 AND 200;
  • 聚簇索引物理有序,顺序IO,效率极高
  • 非聚簇索引需要多次回表,随机IO,效率较低

六、设计建议

聚簇索引设计原则

  1. 选择单调递增的列(如自增主键):避免页分裂
  2. 不要用UUID:无序插入导致频繁页分裂
  3. 尽量短小:减少非聚簇索引的存储空间

非聚簇索引优化

  1. 建立组合索引:覆盖更多查询场景
  2. 利用覆盖索引:查询列都在索引中,避免回表
  3. 控制索引数量:每个索引都会占用空间并影响写入性能

反例与正例

-- ❌ 不推荐:UUID作为主键
CREATE TABLE bad_design (
    id VARCHAR(36) PRIMARY KEY,  -- UUID无序
    data TEXT
);

-- ✅ 推荐:自增ID作为主键
CREATE TABLE good_design (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    uuid VARCHAR(36) UNIQUE,
    data TEXT,
    INDEX idx_uuid (uuid)  -- UUID作为辅助索引
);

七、总结

聚簇索引是数据的物理组织方式,决定了数据如何存储;非聚簇索引是数据的逻辑访问路径,提供快速查找能力。

核心记忆点

  • 聚簇索引 = 按索引顺序存储数据(数据即索引)
  • 非聚簇索引 = 索引指向数据位置(索引是指针)
  • InnoDB必有聚簇索引,通常是主键
  • 理解"回表"概念是优化查询的关键
0
博主关闭了所有页面的评论