mysql中非聚簇索引是什么_mysql非聚簇索引基础说明

来源:这里教程网 时间:2026-02-28 20:43:10 作者:

非聚簇索引(也叫二级索引、辅助索引)是 MySQL 中一种将索引与数据物理存储分离的索引结构。它不改变表中数据的实际存放顺序,叶子节点不存完整行记录,而是只存索引列值 + 对应主键值。

非聚簇索引的核心特点

在 InnoDB 引擎中:

每个非聚簇索引的 B+ 树叶子节点,存储的是「索引字段值」和「该行对应的主键值」,不是整行数据; 查询时若需要非索引字段(比如
SELECT name FROM user WHERE email = 'a@b.com'
),必须先通过 email 索引找到主键 id,再用这个 id 回到聚簇索引树中查出 name —— 这个过程叫「回表」;
一个表可以有多个非聚簇索引,数量上限为 249 个(MySQL 8.0+); 它不占用数据页空间,但会额外消耗磁盘和内存,且每次 INSERT/UPDATE/DELETE 都需同步更新所有相关非聚簇索引。

为什么非聚簇索引要存主键而不是行地址?

InnoDB 的设计决定:数据按主键顺序物理组织(聚簇索引),行位置可能随插入、删除、页分裂而变动。直接存行地址不可靠,而主键稳定唯一,能长期准确指向目标记录。

例如建表:

CREATE TABLE user (id INT PRIMARY KEY, name VARCHAR(32), email VARCHAR(64));

再为

email
建索引:
CREATE INDEX idx_email ON user(email);

此时
idx_email
就是非聚簇索引,其叶子节点内容类似:
[email='a@b.com'] → 主键 id=1024
后续查
SELECT * FROM user WHERE email = 'a@b.com'
就得走两次 B+ 树查找。

哪些情况能避免回表?

当查询语句所需的全部字段,都包含在非聚簇索引中时,就无需回表 —— 这叫「覆盖索引」。

SELECT email FROM user WHERE email = 'a@b.com'
→ 只查索引字段,直接返回;
SELECT email, id FROM user WHERE email = 'a@b.com'
→ id 是主键,已在索引叶子中,仍属覆盖;
SELECT email, name FROM user WHERE email = 'a@b.com'
→ name 不在索引里,必须回表。

MyISAM 和 InnoDB 的非聚簇索引差异

MyISAM 的非聚簇索引叶子节点存的是「行的物理地址(即 .MYD 文件中的偏移量)」,而 InnoDB 存的是「主键值」。这是引擎底层设计的根本区别:MyISAM 数据文件本身无序,InnoDB 数据强制按主键有序。

因此,在 InnoDB 中,主键选择很重要 —— 主键越短(如 INT 而非 UUID),非聚簇索引占用空间就越小,性能损耗也越低。

相关推荐