B+ 树特点:
[30|60]
/ | \\
[10|20] [40|50] [70|80]
| | |
叶子节点通过链表连接
为什么用 B+ 树: | 对比 | B 树 | B+ 树 | |——|——|——-| | 数据存储 | 所有节点 | 仅叶子节点 | | 范围查询 | 需中序遍历 | 叶子链表直接遍历 | | 磁盘 IO | 较多 | 较少 |
| 类型 | 叶子节点存储 | 数量 |
|---|---|---|
| 聚簇索引 | 完整行数据 | 1 个 |
| 非聚簇索引 | 主键值 | 多个 |
回表:二级索引 → 主键 → 聚簇索引查完整数据
查询列都在索引中,无需回表:
-- 索引 idx(name, age)
SELECT name, age FROM user WHERE name = 'Tom'; -- 覆盖索引
SELECT * FROM user WHERE name = 'Tom'; -- 需要回表
联合索引 (a, b, c) 的使用:
| 查询条件 | 是否走索引 |
|---|---|
| a = 1 | ✅ |
| a = 1 AND b = 2 | ✅ |
| a = 1 AND b = 2 AND c = 3 | ✅ |
| b = 2 | ❌ |
| a = 1 AND c = 3 | ✅ 部分(只用 a) |
-- 1. 对索引列使用函数
WHERE YEAR(create_time) = 2024 -- ❌
WHERE create_time >= '2024-01-01' -- ✅
-- 2. 隐式类型转换
WHERE phone = 13800138000 -- ❌ phone 是 varchar
WHERE phone = '13800138000' -- ✅
-- 3. LIKE 左模糊
WHERE name LIKE '%Tom' -- ❌
WHERE name LIKE 'Tom%' -- ✅
-- 4. OR 条件(部分列无索引)
WHERE a = 1 OR b = 2 -- b 无索引则全表扫描
-- 5. != 或 NOT IN
WHERE status != 1 -- 可能全表扫描
Index Condition Pushdown:将 WHERE 条件下推到存储引擎层过滤