文章目录
- 1. 使用MySQL索引的原因
- 2. 索引的三种常见底层数据结构以及优缺点
- 3. 索引的常见类型以及它是如何发挥作用的?
- 4. MyISAM 和 InnoDB 实现 B +树索引方式的区别是什么?
- 5. InnoDB 为什么设计 B+ 树索引?
- 6. 什么是覆盖索引和索引下推?
- 8. 哪些操作会导致索引失效?
- 9. 字符串加索引
- 10. 什么是最左匹配原则
- 11. 索引的应用场景
- 12. 索引的分类
对MySQL索引底层不了解可以可以阅读这两篇文章进行了解
【MySQL】深入理解B+树索引_起名方面没有灵感的博客-CSDN博客
【MySQL】深入学习B+索引的使用_起名方面没有灵感的博客-CSDN博客
1. 使用MySQL索引的原因
- 使用索引是为了提高数据的查询效率。
- 对于数据库的表而言,索引就像它的目录。
- 创建唯一索引,可以保证数据库中每一行数据的唯一性。
- 帮助引擎层避免排序和临时表
- 如果没有索引,在对表中记录进行排序的时候,需要将记录加载到内存,然后使用一些排序算法在内存中对这些记录排序。
- 如果没有索引,就需要建立一个临时表,将符合结果的记录填入这个临时表中,再将结果发送到客户端。
- 将随机IO变为顺序IO,加快表和表之间的连接。
2. 索引的三种常见底层数据结构以及优缺点
索引有三种底层数据结构,分别是哈希表、有序数组和树
- 哈希表:哈希表适合等值查询的场景,不适合范围查询
- 有序数组:只适合静态存储引擎,等值和范围查询性能好,但更新数据成本高。
- N叉树:由于读写上的性能优点以及适配磁盘访问模式以及广泛应用在数据库引擎中
- 以 InnoDB 的一个整数字段索引为例,这个 N 差不多是 1200。棵树高是 4 的时候,就可以存 1200 的 3 次方个值,这已经 17 亿了。考虑到树根的数据块总是在内存中的,一个 10 亿行的表上一个整数字段的索引,查找一个值最多只需要访问 3 次磁盘。其实,树的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。
3. 索引的常见类型以及它是如何发挥作用的?
索引类型分为聚簇索引、二级索引和联合索引
- 聚簇索引:聚簇索引使用记录主键值的大小进行记录和页的排序,并且叶子节点存储的是完整的用户记录。
- 二级索引:二级索引不再以主键的值进行排序。而是索引中指定的某个列作为大小作为数据页、页中记录的排序规则等等。并且,二级索引⼦节点存储的并不是完整的⽤户记录,⽽是某个列+主键这两个列的值。
- 当在二级索引中定位到具体的记录的时候,必须根据主键值去聚簇索引中再查找一遍完整的用户记录,这个过程也称为回表。
4. MyISAM 和 InnoDB 实现 B +树索引方式的区别是什么?
- InnoDB 存储引擎:在InnoDB中,索引即数据。也就是聚簇索引的那棵B+树的叶⼦节点中已经把所有完整的⽤户记录都包含了。
- MyISAM 存储引擎:MyISAM的索引⽅案虽然也 使⽤树形结构,但是却将索引和数据分开存储。索引的叶子节点中存储的不是完整数据,而是主键+行号的组合,通过索引找到行号,再通过行号找到对应的记录。也就是说MyISAM的每一个索引都是二级索引。
5. InnoDB 为什么设计 B+ 树索引?
- 哈希索引虽然能提供O(1)复杂度查询,但对范围查询和排序却无法很好的支持,最终会导致全表扫描。
- B 树能够在非叶子节点存储数据,但会导致在查询连续数据可能带来更多的随机 IO。
- 而 B+ 树的所有叶节点可以通过指针来相互连接,减少顺序遍历带来的随机 IO。
什么是B树?
B树和平衡二叉树的最大区别就是B树属于多叉树。
平衡二叉树的特点:
- 根节点的值大于其左子树中任意一个节点的值,小于其右节点中任意一节点的值,这一规则适用于二叉查找树中的每一个节点。
- AVL树上任意结点的左、右子树的高度差最大为1。
下面是一个3阶B树
可以看到,
除 根结点 外,所有 非叶子结点 都至少有 M/2 = 1.5 取整 = 2 个结点。
每个 结点中 的索引值 都是从小到大排序的。
所有叶子结点都在同一层中。
什么是B+树?
B+树和B树最大的不同是:
- B+树内部有两种结点,一种是索引结点,一种是叶子结点。
- B+树的索引结点并不会保存记录,只用于索引,所有的数据都保存在B+树的叶子结点中。而B树则是所有结点都会保存数据。
- B+树的叶子结点都会被连成一条链表。叶子本身按索引值的大小从小到大进行排序。即这条链表是 从小到大的。多了条链表方便范围查找数据。
- B树的所有索引值是不会重复的,而B+树 非叶子结点的索引值 最终一定会全部出现在 叶子结点中。
6. 什么是覆盖索引和索引下推?
- 覆盖索引
- 在某个查询里面,索引 k 已经“覆盖了”我们的查询需求,称为覆盖索引。
- 覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
- 之所以能减少树的搜索次数,比如说查询key1,使用了key1的索引,这个B+树的数据就包含了主键值+key1,因此不需要回表操作,减少了树的搜索次数。
- 索引下推
- MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
- 若不使用索引下推优化时,获取下一行,首先读取索引信息,然后根据索引将整行数据读取出来。然后再通过where条件判断当前数据是否符合条件,符合返回数据。
- 若使用索引下推,获取下一行的索引信息。检查索引中存储的列信息是否符合索引条件,如果符合将整行数据读取出来,如果不符合跳过读取下一行。接着用剩余的判断条件,判断此行数据是否符合要求,符合要求返回数据。
8. 哪些操作会导致索引失效?
- 对索引使用左或者左右模糊匹配,也就是 like %xx 或者 like %xx% 这两种方式都会造成索引失效。原因在于查询的结果可能是多个,不知道从哪个索引值开始比较,于是就只能通过全表扫描的方式来查询。
- 对索引进行函数/对索引进行表达式计算,因为索引保持的是索引字段的原始值,而不是经过函数计算的值,自然就没办法走索引。
- 对索引进行隐式转换相当于使用了新函数。
- WHERE 子句中的 OR语句,只要有条件列不是索引列,就会进行全表扫描。
9. 字符串加索引
- 字符串加索引,如果直接使用完整字符串建立索引,会比较占用空间。
- 因此会创建前缀索引,但会增加查询扫描次数,并且不能使用覆盖索引。
- 之所会增加查询扫描次数,是因为前缀符合条件的话,需要进行回表操作判断是不是符合条件
- 覆盖索引是说索引 k 已经“覆盖了”我们的查询需求,但是前缀索引是拿字符串前几个字符存放进索引的。
- 并且使用前缀索引不能完成排序需求。
- 因为前缀索引是拿字符串前几个字符存放进索引的。相同的前缀在索引中是有序的,但是它们完整的字符串未必是有序的。
10. 什么是最左匹配原则
最左匹配原则就是指在联合索引中,如果你的 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配。MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。
比如对(a,b,c)建立联合索引,如果查询条件第一个不包含a,那么就不会使用索引。
最左前缀匹配原则: 在MySQL建立联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。
11. 索引的应用场景
- 不需要创建索引的情况
- 表记录太少,二级索引有时候需要回表操作,记录太少的话全表搜索的速度比索引查找+回表的效率更高。
- 经常增删改的表。CRUD会对B+树的记录的排序造成破坏。
- 数据重复且分布平均的表字段,因此应该只为经常查询和经常排序的数据列建立索引。
- Where条件里用不到的字段不创建索引。因为MySQL维护一个索引树也需要耗费空间。
- 需要创建索引的情况
- 主键自动建立唯一索引
- 频繁作为查询的条件的字段应该创建索引
- 查询中与其他表关联的字段,外键关系建立索引
- 查询中排序的字段,排序字段若通过索引去访问将大大提高排序的速度
- 查询中统计或者分组字段
12. 索引的分类
详细可以看【MySQL】1.索引_起名方面没有灵感的博客-CSDN博客
参考:
- 60 道 MySQL 精选面试题👍
- InnoDB为什么要选择B+树来存储数据 - 腾讯云开发者社区-腾讯云 (tencent.com)
- B树和B+树_ZJE_ANDY的博客-CSDN博客_b树和b+树
- 索引下推详解_走出半生仍是少年的博客-CSDN博客_索引下推
- MYSQL | 最左匹配原则的原理 - 腾讯云开发者社区-腾讯云 (tencent.com)
- 索引的应用场景(哪些情况需要,哪些不需要)_温柔的ci的博客-CSDN博客_索引适用以及不适用的场景