面试官:MySQL 索引是什么?这道题答全的人真不多

面试被问到 MySQL 索引,多数人的回答停留在"加快查询"四个字。

这话对,但没用。

索引真正要讲清楚的,是一份排好序的目录:

索引可以理解成一份排好序的目录,它通过维护特定的数据结构,让数据库能够更快定位目标数据,而不必每次都扫描整张表。

代价也实打实------写数据时要顺手维护它,空间上多占一份。

用写入和空间换查询速度,这层账得算明白。

索引到底是什么

拿查字典说最清楚。

没有目录,找一个字得从第一页翻到最后一页,数据库管这叫全表扫描。

有了拼音目录,先定位到那一页再细看,这就是索引查找。

MySQL 的索引就是这张目录。

它是存储引擎层建的辅助数据结构, 以 InnoDB 的 B+ 树索引为例,它会按照索引列的值组织数据,使查询能够沿着索引结构快速定位目标记录。

说白了,索引在存储引擎层,不在 Server 层。

不同存储引擎的索引实现走的不是一条路,InnoDB 和 MyISAM 就是两套完全不同的方案,后面细说。

底层为什么是 B+ 树

面试官八成会追问:

凭什么用 B+ 树,不用 B 树?

官方文档写的是 "B-tree",但面试和平时交流里一定说 B+ 树。

它两个特征最关键:

非叶子节点只存索引键和指针,不存数据,所以同一层能塞下更多键,树更矮;

所有叶子节点用链表串起来,天然有序,范围查询和排序顺着链表走就行。

树矮的意义在 IO。

B+ 树的高度通常比较低,一次索引查找只需要经过少量层级;

如果相关索引页不在 Buffer Pool 中,才需要从磁盘读取,因此能够显著减少磁盘 IO。

树的高度越低,查找需要访问的节点越少,通常也意味着更少的 IO 开销。

二叉树太高、哈希表不支持范围查询和排序,都不如 B+ 树全面。

聚簇、非聚簇,还有回表

这块最容易答偏。

InnoDB 里索引分两类。

聚簇索引的叶子直接存整行,一张表只有一个,通常就是主键。

二级索引的叶子存的是主键值,不是整行。

问题就出在二级索引上。

你写 where name = '张三',引擎先在 name 索引里找到张三对应的主键,再拿主键去聚簇索引把整行捞出来。这多走的一步叫回表。

MyISAM 是另一条路:

它的索引叶子存行号,拿到行号去数据文件按位置读。

所以 MyISAM 没有聚簇的概念,索引全是二级的。

索引不只是加快查询

检索提速、降 IO 是本职。

一张千万级的订单表跑 where order_id = 16815,没索引只能全表扫描把每页读一遍,IO 开销极大;

建了 order_id 索引,可以沿着 B+ 树快速定位目标记录,大幅减少需要扫描的数据页和 IO 开销。

ORDER BYGROUP BY 在满足索引顺序等条件时,可以利用索引本身的有序性减少排序开销,而不一定需要额外的排序操作。

具体是否使用索引,要结合执行计划判断。

看执行计划 Extra 列,本来会显示 Using filesort,用了索引有序性这一项就消失。

唯一索引还能保数据完整。

主键和唯一索引靠唯一约束挡脏数据,比如用户表给 phone 建唯一索引,重复手机号直接写不进去。这比在 Java 代码里判重可靠,数据库层约束是硬性的,并发下也不会漏。

作用 说明
检索提速 大幅减少需要扫描的数据页和 IO 开销
排序 / 分组 利用索引有序性,减少额外排序开销
数据完整 唯一 / 主键索引挡住重复脏数据

但索引不是免费的。

每次写入,索引都得跟着更新。

B+ 树插入可能引发页分裂,删除可能触发页合并,都是实打实的额外开销。

所以写多读少的表,索引越多写入越慢,反而成了一种负担。

索引本身也会占用额外存储空间,表上索引越多,占用的空间和维护成本通常也越高,不是越多越好。索引多了,优化器选择执行计划的成本也可能增加。

还有一些常见场景会让普通索引难以有效利用,比如 LIKE '%张' 这种左模糊查询、对索引列进行函数计算,以及部分隐式类型转换。

遇到这类情况不要凭感觉判断,最好结合 EXPLAIN 查看实际执行计划。

必要时再考虑其他优化方案,而不是直接依赖 FORCE INDEX

索引难以有效利用的常见场景 原因
like '%张' 左模糊 前缀不确定,B+ 树有序性用不上
字段套函数 where year(createtime)=2024 索引列被计算,无法命中
类型不匹配 where phone = 13800000000(phone 是字符串) 隐式转换导致索引失效

所以这道题别只说"加快查询"。

从 B+ 树结构、InnoDB 的回表、到作用和优缺点体系化讲一遍,面试官才信你是真懂。

相关推荐
学长毕业设计2 小时前
基于SpringBoot的公益基金管理系统(源码+文档+讲解视频)
java·spring boot·后端
东小西2 小时前
【SAA实战】第 3 篇 · 工具调用全攻略:把业务能力交给 Agent 自己调度
java·后端·spring
东小西2 小时前
【SAA实战】第 4 篇 · Agent 短期记忆:saver 让 Agent 跨轮记得住(threadId 隔离)
java·后端·spring
阿kun要赚马内3 小时前
MySQL 索引基础
后端·mysql
码事漫谈3 小时前
我啥都能做,却不知道做什么了
后端
geovindu3 小时前
CSharp: 万年历
开发语言·后端·c#·.net
独泪了无痕5 小时前
SpringBoot Event事件机制,轻松实现业务解耦
spring boot·后端·spring
悲且狂6 小时前
SpringBoot项目改造注意事项(旧项目框架复用)
java·spring boot·后端
敲代码的嘎仔6 小时前
28届后端开发-海康威视日常实习一面(已OC)
java·开发语言·后端·面试·海康威视·实习·大厂
IT_陈寒7 小时前
JavaScript数组排序踩的坑,差点让我加班到凌晨
前端·人工智能·后端