MySQL索引知识 一文全了解,面试前必备

Posted Z-hhhhh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL索引知识 一文全了解,面试前必备相关的知识,希望对你有一定的参考价值。

索引

索引(index)是帮助mysql高效获取数据结构。

索引的本质:索引是数据结构,索引的目的是提高查询效率,可以类比新华字典的拼音部分目录,可以根据目录快速定位到每个字的地址。加入没有目录。就需要把字典从头翻到尾,遍历一遍。

索引的优劣

索引的优势

  1. ​ 提高数据检索的效率,降低数据库IO成本
  2. ​ 通过索引对数据进行排序,能够降低排序成本,降低CPU的消耗
  3. ​ 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间

索引的劣势

  1. ​ 要创建和维护索引都需要消耗时间和物理空间,这些消耗为随着数据量的增加二增加。
  2. ​ 对表的数据进行增删改的时候,索引也需要进行维护,这就降低了整体的维护速度。
  3. ​ 当表比较小的时候,直接进行全表扫描反而效率更高

为什么使用自增列做主键

  1. 如果定义了主键(PRIMARY KEY),那么InnerDB(5.5.8版本后Mysql的默认数据库引擎)会选择主键作为聚集索引。如果没有显示定义主键,那么InnerDB会选择第一个不包含NULL值得唯一所以作为主键索引,如果也不存在这样得唯一索引,那么InnerDB会简历一个隐性的聚集索引,这个索引会就像一个主键一样,随着行的增加而递增。
  2. 由于数据记录本身被存于主索引(B+Tree)的叶子节点上,这就要求同一个叶子节点内同的各条数据记录按照主键的顺序存放,每当有新的记录插入时,MySQL会根据其主键插入到适当的位置,如果表使用自增主键,那么每次有新的记录插入时,该记录就会按照顺序添加当前的索引到后续位置上,当这一页写满(InnerDB默认时达到15/16的情况下),就会自动开辟新的一页。
  3. 如果使用非自增主键(身份证号、学号等),因为这样的主键不能保证完全连续,所以每次插入新的记录时,索引就会插入到中间位置。这就导致为了加入新的索引时,需要移动后面的索引数据,需要从磁盘上进行读写操作,同时频繁的移动和分页会早上大量的磁盘碎片,使索引结构不够紧凑,需要通过OPTIMIZE TBALE(优化表)来重新建表并优化填充页面。

BTree和B+Tree区别

BTree

​ BTree是对平衡二叉树的改造,通过增加树的叉数,将树从高瘦型转变成矮胖,这样数据深度就降低了,从而降低磁盘IO的次数,这样查询数据的效率就提高了。

B树图如下:

在这里插入图片描述

主要特点:

  1. ​ B树的节点中存储多个元素,每个内节点有多个分叉。
  2. ​ 节点中的元素包含键值和数据,节点中的键值从大到小排列。
  3. ​ 父节点当中的元素不会出现在子节点中。
  4. ​ 所有的叶子节点都在同一层,叶节点具有相同的深度,也结点之间没有指针连接。

BTree的缺点

  1. ​ B树无法支持范围的快速查询,在查询的过程中需要多次回到根节点重新遍历查找,效率比较低。
  2. ​ 如果data存储的是行记录,行的大小随着列数的增加,空间占用量会增加,这时,一页中可存储的数据量就会减少,树就会变高,磁盘的IO次数也随之增加。

B+Tree树

​ B+Tree树时对B树的升级,主要区别在于非叶子节点是否储存数据的问题

!区别!

​ BTree树在非叶子节点和叶子节点都会存储数据

​ B+Tree树:只在叶子节点才会储存数据,非叶子节点只存键值。叶子节点之间使用双向指针连接,最底层的叶子节点形成了一个双向有序的链表。

叶子结点的左右两侧指针域省略。它的特点就是任何非叶子结点都会在叶结点上再次出现一次,并且所有叶子结点从左到右链接了起来。总体来说,它也具备B树的特性,只是在两个方面有所区别。第一就是查找元素时,即使在非叶子结点找到了目标值,它也只是用来索引的,还需要继续找到它在叶子结点的位置。第二就是如果要遍历,只需要遍历一次叶子结点即可。B+树的结构也十分适合范围查找,只需要找到范围的最小值所在位置,然后沿链表遍历即可。

在这里插入图片描述

B树 VS B+树(B+树更加适合数据库索引)

​ ①B+树的磁盘读写代价更低

B+树的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说IO读写次数也就降低了;

​ ②B+树查询效率更加稳定

由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当;

​ ③B+树便于范围查询(最重要的原因,范围查找是数据库的常态)

B树在提高了IO性能的同时并没有解决元素遍历的我效率低下的问题,正是为了解决这个问题,B+树应用而生。B+树只需要去遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作或者说效率太低;

hash索引和BTree区别

hash索引,其检索效率虽然高,可以一次性定位到目标,不像B树那样从根节点到叶子节点那样 需要多次IO 访问

但是hash索引却具有五个缺点,导致我们在Mysql中不使用它。

​ ①hash索引仅仅能满足= IN <> 这三种查询,无法支持范围查询

​ 由于hash索引时进行hash计算,得到hash值,索引它只能进行等值过滤,经过hash算法处理后的hash值无法比较原来的大小,所以不能进行范围比较,

​ ②hash索引无法被用来数据排序

​ 还是由于计算hash值,和原来的大小无法保持一致,因此无法进行排序

​ ③hash索引不能不能利用部分索引键查询

​ 对于组合索引,hash索引在计算hash值的时候时合并在一起计算的,不能单独计算hash值,所以当使用组合索引时,hash索引就无能为力了

​ ④hash索引在任何时候都无法避免扫描表

​ Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。

​ ⑤hash碰撞

​ 当遇到大量hash值相同的情况下,将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。

索引失效

​ 1、like以%开头,索引无效,但是若是前缀没有%,后缀有%时,索引依旧有效

​ 2、or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效

​ 3、组合索引,不是使用第一列索引,索引失效。

​ 4、数据类型出现隐式转化。如varchar不加单引号的话可能会自动转换为int型,使索引无效,产生全表扫描。

​ 5、如果mysql估计使用全表扫描要比使用索引快,则不使用索引

以上是关于MySQL索引知识 一文全了解,面试前必备的主要内容,如果未能解决你的问题,请参考以下文章

一文彻底搞懂MySQL基础:B树和B+树的区别

一文彻底搞懂MySQL基础:B树和B+树的区别

❤『知识集锦』一文搞懂mysql索引!!(建议收藏)

一文了解mysql事务实现

Java找工作必备知识——day03MySQL索引原理

面试必看!凭借着这份 MySQL 高频面试题,我拿到了京东,字节的offer!