指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
关于mysql索引类型总结
这里主要拿innob分析,就目前来看,默认都是用innodb, myisam 现在使用很少, 过去总是一直说这个索引,其实呢,按适用类型来分的话,就两种:
  • 主键索引(聚簇索引(Clustered Index))
  • 辅助索引(辅助索引包含很多: 前缀索引 组合索引 全文索引等)
主键索引的结构:
  • 索引数据和表的行数据存放在一起。
  • 主键索引的叶子节点包含了完整的行数据(数据页)。

如下:

[ 50 ]                     ← 内部节点(索引键)
/      \
+----------------+    +---------------------+
| [10, 20, 30]   |    | [50, 70, 90]        |   ← 叶子节点(含整行数据)
+----------------+    +---------------------+
↓                         ↓
+-----------------+       +-----------------+
| PK=10, Row1     |       | PK=50, Row4     |
| name: 'A'       |       | name: 'D'       |
| age: 20         |       | age: 30         |
+-----------------+       +-----------------+

        +-----------------+       +-----------------+
        | PK=20, Row2     |       | PK=70, Row5     |
        | name: 'B'       |       | name: 'E'       |
        | age: 25         |       | age: 22         |
        +-----------------+       +-----------------+

        +-----------------+       +-----------------+
        | PK=30, Row3     |       | PK=90, Row6     |
        | name: 'C'       |       | name: 'F'       |
        | age: 28         |       | age: 24         |
        +-----------------+       +-----------------+
辅助索引的结构:
  • 辅助索引的叶子节点 只包含索引列 + 主键列
  • 并不包含整行数据(与聚簇索引不同!)
  • 查询时,如果你要获取其他字段,就必须 “回表”

如下:

✅ 场景设定(继续使用原表结构):
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    age INT,
    INDEX idx_name(name)  -- 辅助索引!
);
idnameage
10Alice22
20Bob25
30Carol28
40Dave30

🎯 图一:辅助索引结构图(idx_name)
                    [ Carol ]
                    /      \
     +----------------+     +-------------------+
     | Alice | Bob    |     | Carol | Dave      |   ← 叶子节点
     +----------------+     +-------------------+
           ↓                      ↓
     +-------------+       +-------------+
     | name=Alice  |       | name=Carol  |
     | PK=10       |       | PK=30       |
     +-------------+       +-------------+
     | name=Bob    |       | name=Dave   |
     | PK=20       |       | PK=40       |
     +-------------+       +-------------+

             ←←←←←←←←←←   双向链表连接   →→→→→→→→→→

🔁 图二:辅助索引 → 回表过程

执行 SQL:

SELECT age FROM users WHERE name = 'Carol';

执行流程图 👇

Step 1:
     🔎 辅助索引 idx_name 查 name='Carol'
         ↓
     → 定位到主键值 PK=30

Step 2:
     🔁 回到主键 B+树(聚簇索引)
         ↓
     → 从聚簇索引叶子节点中根据 PK=30 取出整行数据(包含 age 字段)

Step 3:
     🎯 返回结果:age=28

🧠 注意:如果 SELECT 中已经包含 name(即索引字段),那就不用回表。


二者对比, 聚簇索引 vs 辅助索引:

| 特性       | 聚簇索引(主键)       | 辅助索引(非主键字段)         |
| -------- | -------------- | ------------------- |
| 叶子节点内容   | ✅ 主键值 + 整行数据   | ✅ 索引字段 + 主键值(无其他字段) |
| 是否需要回表   | ❌ 不需要(行数据在叶子中) | ✅ 需要(除非查询字段只包含索引字段) |
| 查找效率     | 高              | 稍慢(需要两次树查找)         |
| 索引字段可否重复 | 不可重复(主键)       | 可重复(索引允许重复)         |

✅ 优化建议:
| 场景                   | 优化方式                       |
| -------------------- | -------------------------- |
| 经常根据 name 查询,并只查 id  | ✅ 使用覆盖索引,避免回表              |
| 经常根据 name 查询 + 查 age | 考虑建立**联合索引** (`name, age`) |
| 查询字段包含非索引列           | ✅ 回表不可避免,考虑是否值得            |
| name 很长,性能低          | 可用 `name(10)` 前缀索引 + hash  |

📣 你还可以用 EXPLAIN FORMAT=JSON 看 MySQL 是否进行了回表操作,字段是:

"using_index": true
"using_index_condition": true

额外说明:
MyISAM 引擎:主键索引和辅助索引都是普通的B树索引,数据和索引是分开的。
B树索引的含义:
MyISAM 的索引结构是 B树(而不是 B+树),也是一种平衡多路查找树。
索引文件里记录的是索引键值和指向数据文件中对应行的指针(偏移量)。

InnoDB 引擎:主键索引是聚簇索引,辅助索引的叶子节点存的是主键值。