【大白话说Java面试题 第71题】【Mysql篇】第1题:索引是什么?

📌 PDF :大白话说Java面试题 --- 03-Mysql篇

第1题:索引是什么

📚 回答:

  • 核心考点
    索引是数据库性能优化 的核心手段。大厂面试要求能说出本质(数据结构)作用(快 vs 慢)代价(存储 + 写放大) ,并能解释为什么不是越多越好

1. 索引的本质
  • 定义

    索引是排好序数据结构 (MySQL InnoDB默认为B+Tree),用于快速定位数据行,避免全表扫描。

  • 时间复杂度对比

    • 无索引:全表扫描 O(N)
    • 有索引(B+Tree):O(log N)

2. 索引的工作原理(B+Tree简解)
特性 说明
多路平衡树 每个节点存储多个key,树高度低(通常2~4层)
叶子节点存放数据(聚簇索引)或主键值(二级索引) 数据只存在叶子节点
叶子节点双向链表 支持范围扫描(BETWEEN><
非叶子节点只存key + 指针 可全部缓存在内存中,加速查找

图示逻辑

复制代码
[根节点] → 分支节点 → 叶子节点(数据页)
                  → 叶子节点 → 叶子节点(双向链表)

3. 索引的类型与特点
索引类型 说明 叶子节点内容 是否必须回表
主键索引(聚簇索引) 表的主键自动建立 完整行数据
二级索引(非聚簇索引) 普通/唯一/联合索引 主键值 (需回表)
唯一索引 列值唯一,可null 同二级索引
联合索引 多列组合 主键值
全文索引 文本分词检索 特殊格式 特殊
哈希索引(Memory引擎) 等值查询快 数据指针 不支持范围

关键点

  • 每张表只有一个聚簇索引(主键无则选第一个唯一非空列,再无则隐藏row_id)
  • 二级索引查到的只是主键值,需要再查主键索引 才能得到完整行 → 回表

4. 索引的优缺点(面试必背)
优点 缺点
查询速度提升(O(N) → O(log N)) 占用额外磁盘空间(通常为数据的1%~5%)
唯一索引保证数据唯一性 INSERT/UPDATE/DELETE 变慢(需同步更新索引)
加速排序(ORDER BY 索引过多影响写性能,优化器选错索引
加速分组(GROUP BY 过长字段建索引浪费空间

公式

索引不是越多越好。读多写少 可多建,写多读少需控制数量。


5. 联合索引与最左前缀原则(高频面试题)

联合索引示例INDEX(a, b, c)

查询条件 是否使用索引 使用哪些列
WHERE a = 1 a
WHERE a = 1 AND b = 2 a, b
WHERE a = 1 AND b = 2 AND c = 3 a, b, c
WHERE a = 1 AND c = 3 ✅(部分) a(c用索引下推)
WHERE b = 2 无(缺最左列a)
WHERE a = 1 ORDER BY b a 索引,b 利用排序
WHERE a = 1 ORDER BY c ✅(但需filesort) a 索引,c 不能直接排序

最左前缀原则

  • 查询条件必须从索引最左列开始,且不能跳过中间列
  • 跳过一列,后面的列无法用于索引查找,但可能用于索引下推(ICP)

6. 回表与覆盖索引(大厂深度)

回表

  • 二级索引查到主键 → 再去聚簇索引查完整行
  • 代价:每次回表是一次随机I/O,回表行数多时性能下降

覆盖索引

  • 当查询的所有列 都在索引中时,不需要回表

  • 示例:

    sql 复制代码
    -- 索引:INDEX(name, age)
    SELECT name, age FROM user WHERE name = '张三';  -- 覆盖索引,不回表
    SELECT name, age, id FROM user WHERE name = '张三';  -- 回表(id可能不在索引)

优化技巧:把频繁查询的字段放入联合索引,变成覆盖索引。


7. 索引失效典型场景(面试必考)
场景 原因 示例(假设索引name
函数操作 索引列被计算/函数 WHERE LOWER(name) = 'zhang'
隐式类型转换 字符串列传int WHERE name = 123(转字符串比)
使用 !=<> 不等号很难用索引 WHERE age <> 30
LIKE '%abc' 通配符开头的模糊匹配 WHERE name LIKE '%张'
OR 未全索引 OR两边不全有索引 WHERE name='a' OR age=30(age无索引)
联合索引不遵循最左前缀 缺少最左列 索引(a,b)WHERE b=1

8. 面试官追问示例

Q1:为什么不建议在低基数列(如性别)建索引?

A:低基数(如性别只有男/女)索引选择性差。查询WHERE gender='男'可能返回50%数据,优化器会全表扫描而不是用索引。

Q2:B+TreeB-Tree 区别?

A:B+Tree非叶子节点不存数据,叶子节点存全部数据且双向链表,更适合范围查询和顺序扫描。MySQL InnoDB使用B+Tree。

Q3:主键用UUID有什么问题?

A:UUID随机无序,插入时页分裂频繁,写性能差;且占用16字节,二级索引叶子节点存储主键值,空间浪费大。推荐自增整型/BigInt。

Q4:什么是索引下推(ICP)?

A:MySQL 5.6+优化。联合索引中,存储引擎层先过滤可用的索引列,减少回表次数。比如INDEX(a,c)WHERE a=1 AND c=2,先用c=2过滤再回表。

Q5:一条查询同时有联合索引(a,b)和单列索引a,优化器会选哪个?

A:通常选(a,b),因为能覆盖更多条件。但优化器会基于代价估算(IO+CPU),如果a列重复度高可能走单列。


9. 总结对比表
维度 无索引 有索引
查询速度 慢(全表扫描) 快(O(log N))
写入速度 慢(需维护索引)
磁盘占用 高(额外空间)
维护成本 高(索引选择、重建)

💡 面试官想要的满分总结

"索引本质上是排好序的B+Tree数据结构 ,通过二分查找和树的高度压缩实现快速数据定位,避免全表扫描。

优点是查询效率极高 ,缺点是占用磁盘拖慢写操作

需掌握聚簇/二级索引 区别、最左前缀原则回表与覆盖索引 ,并熟悉索引失效的典型场景(函数、隐式转换、LIKE '%...')。

生产建索引口诀:等值查前置、区分度高的靠前、覆盖索引优化回表、写多读少谨慎加。"


觉得对您有帮助,麻烦 点点关注啦 ,您的关注是我创作的最大动力~ 🎯

相关推荐
AC赳赳老秦7 小时前
OpenClaw碎片时间利用:设置轻量化自动化任务,高效利用职场碎片时间
java·大数据·运维·服务器·数据库·自动化·openclaw
sukioe7 小时前
Linux RPM 方式安装 MySQL 8.0
linux·mysql·adb
钮钴禄·爱因斯晨7 小时前
秋天的第一个项目,飞算JavaAI一小时拿下~
java·人工智能
九皇叔叔8 小时前
VMware 安装 麒麟操作系统
java·开发语言·虚拟机·麒麟操作系统·vmware安装
yuhuofei20218 小时前
【Python入门】Python中字符串相关拓展
android·java·python
oneouto8 小时前
锁与try catch的位置引发的思考
java
Circ.8 小时前
SpringBoot 实现文件上传与下载(完整源码 + 详细教程)
java·spring boot·后端
weixin199701080168 小时前
[特殊字符] 人工抓取数据革命:从“人肉爬虫”到“智能数据工厂”全面转型指南
开发语言·爬虫·python
zzqssliu8 小时前
Spring Boot + XXL-JOB 搭建淘宝代购系统任务调度中心
java·spring boot·后端