MySQL中聚簇索引、二级索引、覆盖索引、回表查询是什么?

1 个回答

  • 罗云海
    只有行动才能说明一切。
    ## 作用 - **聚簇索引(Clustered Index)**:InnoDB 中数据行本身按聚簇索引的键顺序组织在 B+ 树中,叶子节点保存完整数据行。一张 InnoDB 表有且仅有一个聚簇索引,通常就是主键索引。 - **二级索引(Secondary Index)**:除聚簇索引外的其他索引,用于加速非主键列的查询。 - **覆盖索引(Covering Index)**:查询所需字段都能从二级索引中直接获得,无需再回到聚簇索引读取完整行。 - **回表查询**:先通过二级索引找到主键值,再根据主键到聚簇索引中查询完整数据行的过程。 ## 原理 ### 1. 聚簇索引的选择规则 InnoDB 要求表必须按某种顺序物理存放,因此每张表必有一个聚簇索引: 1. 如果显式定义了 `PRIMARY KEY`,主键索引就是聚簇索引; 2. 如果没有主键,但存在 `UNIQUE NOT NULL` 索引,InnoDB 选择第一个满足条件的唯一索引作为聚簇索引; 3. 如果两者都没有,InnoDB 会隐式创建一个 6 字节自增隐藏列 `ROW_ID`,并基于它生成名为 `GEN_CLUST_INDEX` 的聚簇索引。 ### 2. 二级索引的存储内容 二级索引的 B+ 树叶子节点不保存完整数据行,也不保存磁盘地址,而是保存: - 二级索引列的值; - 对应行的聚簇索引键,通常也就是主键值。 例如,对 `name` 建立二级索引后执行: ```sql SELECT * FROM t WHERE name = 'Alice'; ``` 执行过程为: 1. 在 `name` 的二级索引树中找到 `name = 'Alice'` 对应的主键值,例如 `id = 105`; 2. 再拿着 `id = 105` 到聚簇索引中查找完整行数据。 第二步就是**回表查询**。 ### 3. 覆盖索引如何避免回表 如果查询只需要索引中已经包含的列,就可以直接从二级索引返回结果,不必回表。 例如查询只需要 `name` 和 `id`,并建立联合索引: ```sql CREATE INDEX idx_name_id ON t(name, id); ``` 由于二级索引本身保存 `name` 和主键 `id`,查询字段已经被索引覆盖,因此可以直接返回结果,这就是**覆盖索引**。 ### 4. 使用时的注意点 - 二级索引查询若要取索引之外的字段,通常需要回表; - 使用随机、无序的字符串或 UUID 作为聚簇索引键,可能导致随机写入和页分裂,影响性能; - 联合索引需要遵循最左前缀原则,范围查询之后的列可能无法继续用于排序; - 聚簇索引键的选择会影响数据物理组织、写入性能以及二级索引的查询路径。
    发布于 2026-10-25 22:03 •IP属地 宁夏
    举报
    评论
    收藏