DEV Community

Woody
Woody

Posted on • Edited on

About SQL Index

Image description

下面是一份简单明了的 MySQL 索引教程,适合初学者和有一定基础的用户快速上手。


📘 MySQL 索引教程

一、什么是索引?

索引(Index) 是数据库表中的一种数据结构,用于快速查询数据,类似于图书的目录。
它能大大提高 SELECT 查询效率,但也会占用存储空间,并稍微降低 INSERT/UPDATE 的性能。


二、索引的类型

类型 说明
主键索引(PRIMARY KEY) 唯一且不能为空,自动创建索引。
唯一索引(UNIQUE) 保证列中的值唯一。
普通索引(INDEX/KEY) 最基本的索引,没有唯一性限制。
组合索引(Composite Index) 将多个列组成一个索引,适用于多列查询。
全文索引(FULLTEXT) 支持文本搜索,主要用于 CHAR, VARCHAR, TEXT 类型的字段(MyISAM/5.6后InnoDB)。

三、创建索引的方法

1. 创建表时添加索引

CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(100),
    email VARCHAR(100) UNIQUE,
    age INT,
    INDEX idx_username (username)
);
Enter fullscreen mode Exit fullscreen mode

2. 使用 ALTER TABLE 添加索引

-- 添加普通索引
ALTER TABLE users ADD INDEX idx_age (age);

-- 添加唯一索引
ALTER TABLE users ADD UNIQUE idx_email (email);

-- 添加组合索引
ALTER TABLE users ADD INDEX idx_name_age (username, age);
Enter fullscreen mode Exit fullscreen mode

3. 使用 CREATE INDEX

CREATE INDEX idx_username ON users(username);
CREATE UNIQUE INDEX idx_email_unique ON users(email);
Enter fullscreen mode Exit fullscreen mode

四、查看与删除索引

1. 查看索引

SHOW INDEX FROM users;
Enter fullscreen mode Exit fullscreen mode

2. 删除索引

-- 注意:主键索引要用 DROP PRIMARY KEY
DROP INDEX idx_username ON users;

ALTER TABLE users DROP INDEX idx_email;
ALTER TABLE users DROP PRIMARY KEY;
Enter fullscreen mode Exit fullscreen mode

五、索引的使用建议

  • 经常出现在 WHERE、JOIN、ORDER BY 的列应加索引
  • 组合索引中的列顺序要根据查询习惯设计(最左前缀原则)
  • 避免给频繁更新的字段加索引
  • 不要对低选择性的字段(如性别)加索引
  • 全文搜索使用 FULLTEXT 索引

六、常见问题

1. 索引为什么不起作用?

  • 查询语句没有使用最左前缀
  • 使用了 ORLIKE '%xxx' 等不利于索引的操作
  • 数据量太小,优化器认为全表扫描更快

2. 如何分析索引是否使用?

使用 EXPLAIN 关键字:

EXPLAIN SELECT * FROM users WHERE username = 'Tom';
Enter fullscreen mode Exit fullscreen mode

是否需要我为你提供具体的优化案例或实际项目中的索引设计建议?


底层B+tree

是的,MySQL 中索引的底层原理主要是基于树结构,但不是普通的树,而是B+树(B+Tree)


✅ 一句话总结:

MySQL 的大多数索引(特别是 InnoDB 引擎)是基于 B+树 实现的。


👇 详细解释如下:

1. B+树 vs 二叉树 / 哈希表

  • MySQL 不是用二叉树,因为数据量大时树太高,查找慢。
  • 也不是哈希表(除非你用的是哈希索引,如 MEMORY 引擎),因为哈希不能范围查找、排序。
  • B+树是一种多路平衡查找树,每个节点可以有多个子节点,适合磁盘存储,能减少磁盘 IO。

2. 为什么用 B+树

  • 所有值都存在叶子节点,非叶子节点只存键值(更紧凑)
  • 叶子节点之间有链表结构,方便做范围查询(比如 BETWEENORDER BY
  • 每次查询最多只需 logₙ(N) 次磁盘 I/O,速度非常快
  • 可以很好地支持 范围查找、前缀匹配、排序优化

3. InnoDB 中索引的分类

类型 结构 说明
主键索引 B+树 聚簇索引,叶子节点保存完整数据行
辅助索引(普通索引) B+树 叶子节点保存主键值,不能直接取出行,需要回表
全文索引 倒排索引(不是树) 用于全文搜索(如 MATCH ... AGAINST
空间索引 R-Tree 用于地理空间数据(GIS)

4. 举个例子:

假设你有这样一条 SQL:

SELECT * FROM users WHERE age BETWEEN 20 AND 30;
Enter fullscreen mode Exit fullscreen mode

如果 age 字段有 B+树索引:

  • MySQL 可以快速定位到 age=20 的第一个叶子节点
  • 然后沿着叶子节点链表依次查找直到 age=30
  • 比全表扫描效率高得多

🔚 总结:

  • ✅ MySQL(InnoDB 引擎)索引底层确实是基于 B+树
  • ❌ 不是二叉树,不是哈希表
  • ✅ B+树能高效支持范围查询和排序,是关系型数据库中最常用的索引结构

如果你想了解 B+树的图解或示例,我也可以画图给你看。是否需要?

B+ tree的面试题

B+树作为数据库和文件系统中重要的数据结构,相关的题目多涉及 查找、插入、删除、范围查询页面分裂(Page Split) 等,既有理论分析题,也有实际实现类问题。下面是一些常见且经典的 B+树题目分类,适合用于笔试、面试或深入学习:


🧠 一、基础理解类(适合入门/面试)

这些题主要考察你是否理解 B+树的基本原理:

  1. B+树与B树的区别?为什么数据库用B+树不用B树?
  2. 什么是聚簇索引和非聚簇索引?B+树是如何实现的?
  3. B+树适合的应用场景是什么?为什么适合磁盘存储?
  4. 一个 B+ 树的阶(fanout)如何影响性能?
  5. 什么是回表?B+树如何支持“回表查询”?

🧪 二、操作模拟题(适合理解B+树的行为)

这些题通常要求你模拟 B+ 树的操作,比如插入和删除过程,适合画图理解:

  1. 给定一个空的B+树,按照某个顺序插入一组数字,画出最终的树结构。
  2. 模拟某个节点插入导致的分裂,描述分裂的过程。
  3. 从一棵B+树中删除某个键值,说明是否需要合并或重分布?
  4. 给定一棵B+树,执行范围查找,比如 [10, 50],列出遍历过程。
  5. 叶子节点的链表结构在实际查找中的作用是什么?请举例。

👨‍💻 三、实现类编程题(中高级)

如果你对算法实现感兴趣,这些是比较有挑战的题:

  1. 实现一个支持插入、查找的 B+ 树结构(可以设置阶数)
  2. 实现 B+ 树范围查询功能:range(start_key, end_key)
  3. 实现删除操作,并处理节点合并和重分布
  4. 统计 B+树 的高度、节点个数、叶子个数等属性
  5. 模拟 Page Split 过程,并输出中间步骤

语言可选:C++ / Java / Python 均可,Python 更容易调试,适合教学。


📚 四、数据库实际场景题(适合MySQL方向)

这些题结合实际 MySQL 应用:

  1. 为什么 InnoDB 的主键索引必须是唯一的?聚簇索引在 B+ 树中如何体现?
  2. 为什么建议主键自增?否则会发生什么(比如频繁的中间插入)?
  3. 为什么不建议用 UUID 作为主键?对 B+ 树有什么影响?
  4. 多列联合索引在 B+树中是如何构建的?最左前缀原则如何工作?
  5. Explain 分析中如何判断 B+ 树是否被使用?

🧩 五、综合/趣味题

  1. 在 B+树 上实现类似 LRU Cache 的功能是否可行?
  2. 若 B+ 树用于 SSD 存储,是否还需要那么大的阶数?
  3. 设计一个模拟数据库索引结构的系统,如何使用 B+ 树管理磁盘块?

🛠️ 示例题目(练手)

示例 1:插入模拟

已知一个 B+ 树阶数为 3,向空树中依次插入:5, 10, 15, 20, 25, 30,画出最终树结构。

示例 2:删除模拟

已知一棵 B+ 树包含 5, 10, 15, 20, 25, 30,删除 1015 后的结构是怎样的?

示例 3:查找过程

给定如下 B+ 树结构,执行查询 SELECT * WHERE key BETWEEN 25 AND 50,列出遍历过程。

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.