数据库面试指南


一、MySQL 索引

1.1 B+ 树原理

B+ 树特点

                    [30|60]
                   /   |   \\
            [10|20] [40|50] [70|80]
               |       |       |
            叶子节点通过链表连接

为什么用 B+ 树: | 对比 | B 树 | B+ 树 | |——|——|——-| | 数据存储 | 所有节点 | 仅叶子节点 | | 范围查询 | 需中序遍历 | 叶子链表直接遍历 | | 磁盘 IO | 较多 | 较少 |

1.2 聚簇索引与非聚簇索引

类型 叶子节点存储 数量
聚簇索引 完整行数据 1 个
非聚簇索引 主键值 多个

回表:二级索引 → 主键 → 聚簇索引查完整数据

1.3 覆盖索引

查询列都在索引中,无需回表:

-- 索引 idx(name, age)
SELECT name, age FROM user WHERE name = 'Tom'; -- 覆盖索引
SELECT * FROM user WHERE name = 'Tom';          -- 需要回表

1.4 最左前缀原则

联合索引 (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.5 索引失效场景

-- 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  -- 可能全表扫描

1.6 索引下推(ICP)

Index Condition Pushdown:将 WHERE 条件下推到存储引擎层过滤