后端工程师的高阶面经
邓明
前 Shopee 高级工程师,Beego PMC
6888 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
后端工程师的高阶面经
15
15
1.0x
00:00/00:00
登录|注册

10|数据库索引:为什么MySQL用B+树而不用B树?

非叶子节点没有存放数据,适合放入内存中
叶子节点被串联起来,适合范围查询
高度更低,查询性能更好
叶子节点被链表串联起来
叶子存放了数据,非叶子节点只存放关键字
有 k 个子女的节点必有 k 个关键字
除根节点外,每个节点至少有 [m/2] 个子女,根节点至少有两个子女
每个节点最多有 m 个子女
因为NULL而出现的问题
索引设计不合理引发的线上故障
索引与NULL的特殊之处
数据库不使用索引的情况
MySQL为什么使用B+树
强调索引的理解和优化经验
MySQL对NULL的处理
数据量太小或全表扫描更快
特殊表达式
字段区分度不大
特殊查询条件
对比其他数据结构的特性
维护索引的额外消耗
内存空间消耗
磁盘空间消耗
哈希索引
全文索引
组合索引
前缀索引
唯一索引
覆盖索引
聚簇索引和非聚簇索引
优势
特征
定义与特征
思考题
面试思路总结
面试准备
索引与NULL
数据库不使用索引的情况
MySQL为什么使用B+树
索引的代价
索引的最左匹配原则
索引分类
B+树
数据库索引

该思维导图由 AI 生成,仅供参考

你好,我是大明。
从这节课开始,我们将进入数据库这一章。在实际工作中,数据库设计得好不好、SQL 写得好不好将极大程度影响系统性能。而且,即便是再小的公司,也不可能说没有数据库,所以如果你担忧自己因为没有微服务架构经验难以通过面试,那么数据库就可以成为你反败为胜的一个点。
所以今天我们来聊一聊数据库中的第一个话题——索引。
索引在数据库面试中占据了相当大的比重。但是大部分人面试索引的时候都非常机械,所以难以在面试官心中留下深刻印象。索引是一个理论和实践的结合,今天这节课我先带你分析索引的基本原理,下节课我再在 SQL 优化这一个大主题下进一步带你分析索引设计和优化的实战案例。
索引的内容还是非常多的,尤其是有很多非常细碎的、不成体系的点,记起来非常难。所以这一节课我就会尽量用非常简单的话,以及一些奇妙的比喻来帮助你记忆和索引有关的内容。

前置知识

索引是用来加速查找的数据结构。绝大多数跟存储、查找有关的中间件都有索引功能,但是它们的原理不尽相同。
我们先来了解一下 B+ 树的定义与特征。

B+ 树

B+ 树是一种多叉树,一棵 m 阶的 B+ 树定义如下:
每个节点最多有 m 个子女。
除根节点外,每个节点至少有 [m/2] 个子女,根节点至少有两个子女。
有 k 个子女的节点必有 k 个关键字。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

数据库索引是数据库中非常重要的一部分,本文深入探讨了数据库索引的基本原理和B+树的优势。B+树作为一种多叉树,具有较低的高度、适合范围查询和非叶子节点不存放数据等优势。文章还介绍了索引的分类,包括聚簇索引、非聚簇索引和覆盖索引等。强调了设计覆盖索引以提高查询性能的重要性。此外,还探讨了索引的代价和面试准备中的相关策略。文章通过口诀和基本思路,引导读者了解数据库索引的基本原理和B+树的优势,以及索引的分类和优化方法。文章还深入讨论了MySQL为何使用B+树而不是B树,以及其他数据结构在数据库索引中的适用性。整体而言,本文为读者提供了全面的数据库索引知识,帮助他们快速了解和掌握相关技术要点。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端工程师的高阶面经》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(12)

  • 最新
  • 精选
  • 子休
    关于索引列区分度的问题,这里稍微补充一个例子。 其实也未必所有区分度不高的索引都不会生效,比如一个列里面只有0和1两种值,看上去似乎区分度不高,但是如果0和1的值比例完全失衡,比如是95:5的比例,那么这种索引也有可能是生效。 比如一般的任务表里面,状态字段绝大多数都是“success”,少部分是“failed”,如果你查询的是失败的记录,这个时候状态字段的索引就可以生效了。

    作者回复: 是的,就是这种索引用起来效果不太好,因为区分度太低了。当然,如果你主要查询都是查 failed 的,那么就还挺好用的。

    2023-07-18归属地:上海
    9
  • 死者苏生
    https://zhuanlan.zhihu.com/p/519658576 mongodb用的wiredTiger就是B+树,建议这篇修改下,不要误人子弟

    作者回复: 感谢指正,我重新写一下相关论述。

    2023-07-09归属地:河南
    3
    8
  • 长脖子树
    Mongo用的就是B+树

    作者回复: 感谢指正,我调整一下!

    2023-07-09归属地:浙江
    3
    4
  • 徐石头
    SELECT id, name FROM user_tab WHERE id = 123,这个SQL中需要强调id不是作为主键,因为id如果是主键,就会直接走主键索引,无法体现覆盖索引中只查询索引中的字段的过程,另外联合索引<id,name>中如果SQL改成SELECT id, name,age FROM user_tab WHERE id = 123就无法实现覆盖索引的效果

    作者回复: 赞!说得很准确!

    2023-07-13归属地:湖南
    2
  • sheep
    你有没有遇到过索引设计不合理引发的线上故障? 线上ddl操作,需要删除一个索引,然后新建一个,删除之后,出现堆积大量的慢查询;这时候新建索引会被阻塞住(mdl读锁和写锁),后面的查询也一并阻塞住了。 解决办法是:临时关闭服务对外使用,kill掉创建索引后面的查询,待索引创建成功后,服务再恢复使用

    作者回复: 如果我是面试官,我就会杠,如果不能停掉服务呢?阁下该如何应对?

    2023-09-20归属地:广东
    3
    1
  • peter
    确认一下理解:根据文章内容,索引其实是表的一部分数据,如果表的数据是100M,那么,某个索引包含其中的10M数据,这样共有100M + 10M。这10M是表数据之外的数据,是表数据中某部分数据的一个拷贝。比如,表中有一个字段“name = zhangsan”,建立与该name的索引后,磁盘中有两份name。是这样吗?

    作者回复: 可以这么理解,所以当你在更新数据的时候,MySQL 还需要同步维护索引结构。

    2023-07-08归属地:北京
    1
  • Geek_c1118e
    请教一下老师:InnoDB存储引擎的非主键(辅助索引等)和非聚簇索引是否是一个概念,另外,像MyISM中叶子节点存储地址的也是非聚簇索引,所以非聚簇索引是包含这两种格式吗?(:网上看一些相关概念有点混淆,想确认一下

    作者回复: 我个人认为只是说法不同,本质是一样的。 不同引擎的数据结构是独立的,它们没什么关系,只是说恰好都是类似的结构而已。

    2024-02-11归属地:安徽
  • Singin in the Rain
    关于哈希索引,文中提到『但是 MySQL 的 InnoDB 引擎并不支持这种索引。』这一段表述不是很精确。哈希索引确实用在MEMORY存储引擎中,但是这种索引存在一个变种,自适应哈希索引,InnoDB引擎通过innodb_adaptive_hash_index参数控制在其内部使用。

    作者回复: 赞赞赞。我这里是指我们作为一个用户,是没办法说创建一个哈希索引的。

    2023-08-25归属地:北京
  • 小戴同学
    请教一下: "这个数据行存放在磁盘里,所以触发磁盘 IO 之后能够读取出来。磁盘 IO 是非常慢的,因此回表性能极差,你在实践中要尽可能避免回表"这句话说回表的性能差的原因,但是前面"一个默认的前提就是索引本身会全部装进内存中,只有真实的数据行会放在磁盘上",那使用主键索引也需要走磁盘,性能差别就是拿到主键之后再去拿数据的性能差吗?

    作者回复: 不是的,聚簇索引的非叶子部分是可以直接放在内存的。 话又说回来,如果整个内存不够的话,那么索引还是有可能一直在磁盘上的。

    2023-08-11归属地:北京
    2
  • 江 Nina
    “如果查询条件是 WHERE A = a1 OR B = b1,那么这个查询并不会使用这个索引。” 这个是为什么呢 明白b不会走索引 但是感觉前一个A会走索引啊

    作者回复: 严格来说,它走不走索引,不一定。也就是说,如果 MySQL 用 A 索引能加速查询,也就是扫描的行数少,那么它就用;如果用 A 索引,但是 OR 后面的查询条件比起来,B = b1 命中了很多行,那么就不会用 A 的索引,而是直接扫描。 简单来说,就是 OR 两边的条件,MySQL 认为命中的数据越少,就越倾向于用索引。反过来,就不会用索引。

    2023-08-04归属地:北京
    5
收起评论
显示
设置
留言
12
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部