以下是 MySQL 索引相关的常见面试题及解析,涵盖基础概念、使用场景和优化思路:
答案:索引是一种数据结构(如 B + 树、哈希表等),用于快速定位表中的数据,类似于书籍的目录。作用:
-
加速查询速度(如
WHERE、JOIN、ORDER BY 等操作)。
-
减少数据库扫描的数据量,降低 IO 成本。
答案:
-
主键索引(PRIMARY KEY):唯一标识一条记录,自动创建,不可重复,不能为空。
-
唯一索引(UNIQUE):索引列的值必须唯一,但允许为空(最多一个 NULL)。
-
普通索引(INDEX):最基本的索引,无唯一性约束。
-
组合索引(多列索引):基于多个列创建的索引,遵循 “最左前缀匹配原则”。
-
全文索引(FULLTEXT):用于全文搜索,适用于长文本字段(如
VARCHAR、TEXT)。
-
空间索引(SPATIAL):用于地理空间数据类型(如
GEOMETRY),较少使用。
答案:MySQL 中多数索引(如 InnoDB 的主键索引)基于 B + 树 实现。
-
B + 树 vs B 树:
B + 树的叶子节点形成有序链表,便于范围查询(如 BETWEEN、ORDER BY),而 B 树的非叶子节点也存储数据,导致查询效率不稳定。
-
B + 树 vs 哈希表:
哈希表适用于精确匹配(=),但无法支持范围查询、排序和部分匹配(如 LIKE 'abc%'),而 B + 树可以。
答案:
-
聚簇索引(Clustered Index):
索引的叶子节点存储完整的数据行,InnoDB 中主键索引就是聚簇索引。一个表只能有一个聚簇索引。
-
非聚簇索引(Secondary Index):
叶子节点存储主键值,查询时需先通过非聚簇索引找到主键,再通过聚簇索引获取数据(回表查询)。
答案:对于组合索引(如 (a, b, c)),MySQL 会优先匹配最左列(a),再依次匹配后续列(b、c)。
-
能命中索引的情况:
WHERE a=1、WHERE a=1 AND b=2、WHERE a=1 AND b=2 AND c=3。
-
不能命中索引的情况:
WHERE b=2、WHERE c=3、WHERE a=1 AND c=3(跳过了 b)。
答案:
-
索引列参与计算或使用函数(如
WHERE SUBSTR(name, 1, 3) = 'abc')。
-
使用
NOT IN、!=、<> 等操作符(可能失效,视情况而定)。
-
字符串不加引号(如
WHERE name = 123,实际类型为字符串时会隐式转换)。
-
使用
OR 连接非索引列(如 WHERE a=1 OR b=2,若 b 无索引则索引失效)。
-
LIKE 以通配符开头(如 WHERE name LIKE '%abc')。
-
组合索引不满足最左前缀原则。
答案:
-
避免创建过多索引(索引会降低插入 / 更新 / 删除的效率)。
-
对频繁查询的字段创建索引(如
WHERE、JOIN、ORDER BY 涉及的列)。
-
优先使用组合索引替代多个单列索引(减少索引维护成本)。
-
避免索引列使用函数或计算。
-
对于长字符串,可使用前缀索引(如
INDEX idx_name (name(10)))。
-
通过
EXPLAIN 分析索引使用情况,移除冗余索引。
答案:覆盖索引是指查询的所有字段(SELECT 后的列)都包含在索引中,无需回表查询数据。例如:索引为 (id, name),查询 SELECT id, name FROM user WHERE id=1 可直接通过索引返回结果,效率极高。
答案:InnoDB 中主键索引是聚簇索引,自增 ID 可保证新数据总是插入到当前索引的末尾,避免 B + 树的节点分裂,提高写入性能。若使用 UUID 等无序值,会导致索引节点频繁分裂,增加 IO 开销。
这些问题覆盖了索引的核心概念和实践要点,理解后可应对大多数面试场景。实际面试中可能会结合具体 SQL 语句分析索引是否生效,建议结合 EXPLAIN 工具加深理解。