索引概述
介绍:
索引(Index)是MySQL中用于高效检索数据的有序数据结构。除了存储原始数据外,数据库系统还会维护一些特定的数据结构,这些结构通过特定的引用方式指向实际数据记录。借助这些精心设计的数据结构,数据库能够实现高效的查找算法,从而显著提升查询性能。这类专门用于优化查询性能的数据结构就被称为索引。
通俗来讲,可以把MySQL比作是一个字典,里面存储了海量的数据,那么当你想要查询到字典里的某一个字的具体内容应该怎么办呢?是一页一页地翻阅字典内容,还是说查看字典最开头的“目录”?答案显而易见,“目录”是能快速的帮助我们查找到想要的内容的,而在MySQL中,索引就是整个表的“目录”。
举个例子:

这里有一个数据表,假如我们要来执行一个SQL语句:
select * from user where age = 20;
在没有索引的情况下,MySQL会对数据表的每一行数据进行比对查找,直到整个表都被查找一次,这种行为称作“全表扫描”,是一个非常低性能的操作。

而如果有索引的情况下,及对age字段添加一个索引,我们先假设索引的数据结构是一个二叉树(注意是假设,实际的索引数据结构并不是二叉树,这里只是为了方便理解),那么就会对age字段建立一个二叉树的索引结构:

此时我们再使用该查询语句进行查询,就只需要扫描三次就可以找到数据了,因此,查询效率也得到了极大的提升。
特点
当然,索引虽然好用,但也不全是有点,它也有一定的缺点或者劣势

索引结构
概述
对于MySQL的索引,它是在存储引擎层实现的,可以参考MySQL体系结构图:

不同的存储引擎有不同的索引结构,主要包含如下几种:

上述是 MySQL 中所支持的所有的索引结构,接下来,我们再来看看不同的存储引擎对于索引结构的支持 情况
注意:平时我们说的索引,如果没有特别说明是什么索引,在MySQL中指的都是B+树结构组织的索引。
二叉树
加入说,索引的数据结构是一个二叉树,那么比较理想的情况就是如下图所示:

比根节点小的在左侧节点,大的在右侧,这样也能提升查找性能,比如找到17,则只需要四次扫描就可以,但是有一种情况,当所有的数据是有序插入的情况下,那么二叉树就会退化成为链表,性能就会下降:

所以,如果选择二叉树作为索引结构,会存在以下缺点:
顺序插入时,会形成一个链表,查询性能大大降低。
大数据量情况下,层级较深,检索速度慢
那可以进行优化吗?当然,可以使用平衡二叉树,它会在插入节点的时候使用旋转操作让二叉树保持平衡(左右子树的高度差不大于一),所以平衡二叉树能够避免极端情况下退化为链表。但是呢,也是因为平衡二叉树要保持绝对的平衡,就会出现频繁的左旋右旋操作,应用于数据库中就会带来大量的磁盘io,性能也会降低。
那就再升级一下,红黑树,
红黑树是一颗自平衡二叉树,那这样即使是顺序插入数
据,也会通过变色、旋转,来保持树的平衡,最终形成的数据结构也是一颗平衡的二叉树 ,并且红黑树并不追求绝对的平衡,就大大降低了插入删除时候的旋转操作。 结构如下 :
但是,即使如此,由于红黑树也是一颗二叉树,所以也会存在一个缺点:
大数据量情况下,层级较深,检索速度慢。
所以,在 MySQL 的索引结构中,并没有选择二叉树或者红黑树,而选择的是 B+Tree ,那么什么是
B+Tree 呢?在详解 B+Tree 之前,先来介绍一个 B-Tree 。
B-Tree
B-Tree , B 树是一种多叉路衡查找树,相对于二叉树, B 树每个节点可以有多个分支,即多叉。
以一颗最大度数( max-degree )为 5(5 阶 ) 的 b-tree 为例,那这个 B 树每个节点最多存储 4 个 key , 5
个指针:
ps: 树的度数指的是一个节点的子节点个数。
想要直观地了解b树,可以进入此网站进行实地操作:
https://www.cs.usfca.edu/~gall es/visualization/BTree.html
插入一组数据: 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88
120 268 250 。然后观察一些数据插入过程中,节点的变化情况。
特点:
5 阶的 B 树,每一个节点最多存储 4 个 key ,对应 5 个指针。
一旦节点存储的 key 数量到达 5 ,就会裂变,中间元素向上分裂。
在 B 树中,非叶子节点和叶子节点都会存放数据。
B+Tree
B+Tree 是 B-Tree 的变种,我们以一颗最大度数( max-degree )为 4 ( 4 阶)的 b+tree 为例,来看一
下其结构示意图:
我们可以看到,两部分:
绿色框框起来的部分,是索引部分,仅仅起到索引数据的作用,不存储数据。
红色框框起来的部分,是数据存储部分,在其叶子节点中要存储具体的数据。
插入一组数据: 100 65 169 368 900 556 780 35 215 1200 234 888 158 90 1000 88
120 268 250 。然后观察一些数据插入过程中,节点的变化情况。
最终我们看到, B+Tree 与 B-Tree 相比,主要有以下三点区别:
所有的数据都会出现在叶子节点。
叶子节点形成一个单向链表。
非叶子节点仅仅起到索引数据作用,具体的数据都是在叶子节点存放的。
上述我们所看到的结构是标准的 B+Tree 的数据结构,接下来,我们再来看看 MySQL 中优化之后的
B+Tree 。
MySQL 索引数据结构对经典的 B+Tree 进行了优化。在原 B+Tree 的基础上,增加一个指向相邻叶子节点
的链表指针,就形成了带有顺序指针的 B+Tree ,提高区间访问的性能,利于排序。
Hash
MySQL 中除了支持 B+Tree 索引,还支持一种索引类型 ---Hash 索引。
1). 结构
哈希索引就是采用一定的 hash 算法,将键值换算成新的 hash 值,映射到对应的槽位上,然后存储在 hash表中。
如果两个 ( 或多个 ) 键值,映射到一个相同的槽位上,他们就产生了 hash 冲突(也称为 hash 碰撞),可 以通过链表来解决。
2). 特点
A. Hash 索引只能用于对等比较 (= , in) ,不支持范围查询( between , > , < , ... )
B. 无法利用索引完成排序操作
C. 查询效率高,通常 ( 不存在 hash 冲突的情况 ) 只需要一次检索就可以了,效率通常要高于 B+tree 索
引
3). 存储引擎支持
在 MySQL 中,支持 hash 索引的是 Memory 存储引擎。 而 InnoDB 中具有自适应 hash 功能, hash 索引是
InnoDB 存储引擎根据 B+Tree 索引在指定条件下自动构建的。
免责声明
此文章内容均来自”黑马程序员“的免费公开教程,用于巩固自己所学的知识以及分享给感兴趣的人,如果想要系统且详细的学习,推荐如下链接:黑马程序员 MySQL数据库入门到精通,从mysql安装到mysql高级、mysql优化全囊括_哔哩哔哩_bilibili
所有评论(0)