MySQL加索引为什么能更快



前言

提示:这里可以添加本文要记录的大概内容:

MySQL在高数据量查询的情况下要求必须使用索引,那么为什么一定要求要使用索引呢?索引的为什么能使查询变得更快?


提示:以下是本篇文章正文内容,下面案例可供参考

一、什么是索引?

在mysql中,索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。通过索引,查询数据时不用读完记录的所有信息,而只是查询索引列即可。

二、索引解读

在MySQL的中,索引在大数据量查询的情况下必须用到索引,因为索引是类似于目录。如果不使用索引,数据会零散的保存在磁盘块中,查询数据需要挨个遍历每一个磁盘块,直到找到数据为止,使用索引后会将磁盘块以树桩结构保存,查询数据时会大大降低磁盘块的访问数量。想象一下,每条数据的查询都是一个io扫描的话,假设一张表有一百万条数据,你要找的数据刚好就是最后一条,那么就要进行一百万次io,这样就使数据库的性能大幅度降低了。索引就是解决这样的问题的。

那么问题来了,为什么索引能解决这样的问题呢?
首先,我们要了解索引使用的数据结构,MySQL 中存储索引用的一般都是 B + 树。它的数据都存放在叶子节点中,同时叶子节点之间还添加了指针形成了链表。有点像 HashMap 的底层实现,数组 + 链表的结构。

关键字:B+树。

要知道什么是B+树,就要先知道什么是二叉树,红黑树。

二叉树:
1,本身是有序树;
2,树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2;
如图:
在这里插入图片描述
二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大
二叉树简单理解就是,比我大的放右边,比我小的放左边。这样就能二叉寻找了,但是又个问题:
假设数字是有序的,例如,数据库表的id是自增的,那么后面的每一位数都会在右边,二叉树直接就变成链表了。可见,二叉树hold不住。
那就使用二叉树的进阶版,红黑树。

红黑树
每个节点或者是黑色,或者是红色。
根节点是黑色。
每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点]
如果一个节点是红色的,则它的子节点必须是黑色的。
从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。[这里指到叶子节点的路径]
如图
在这里插入图片描述
简单的说,就是插入的节点,会取到中间点作为父节点。例如:一次插入三个数, 1 ,2,3。按照二叉树的话,就是链表结构了,1->2->3。但是红黑树会自动调整,取出2作为上层,左边为1,右边为3。
红黑树解决了二叉树成为链表的尴尬情况了,但是同样的,又衍生出了新的问题。数据库在插入数据的时候,用到红黑树的话,会频繁的变更树的结构。并且红黑树最大的问题是,没有办法控制树的高度,假设红黑树有一千层的话,而想要拿到的数据又刚好在最底层,那么在查询的时候就会去做相对应的IO磁盘扫描。依然造成很大程度的资源损耗。
所以,如果数据库索引用红黑树结构的话,还是hold不住的。

B+树
如图:
在这里插入图片描述

B+树也是多路平衡查找树。
B+树中只有叶子节点存储真实的数据,非叶节点只存储键。在MySQL中,这里所说的真实数据,可能是行的全部数据(如Innodb的聚簇索引),也可能只是行的主键(如Innodb的辅助索引),或者是行所在的地址(如MyIsam的非聚簇索引)。
(1)B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样。
(2)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。
(3)非叶子节点的子节点数=关键字数(百度百科。根据各种资料,这里有两种算法的实现方式,另一种为非叶节点的关键字数=子节点数-1(维基百科),虽然数据排列结构不一样,但其原理还是一样的。Mysql 的 B+树是用第一种方式实现)。

B+树可以说是为了磁盘而生的,因为B+树的所有数据都存在叶子节点中,包存了父节点的指针,最重要的是,B+树最高只有三层,也就是说,无论数据在哪,最多只需要三次IO扫描便可以拿到数据。大大的节省了IO磁盘扫描次数。所以索引有利于增加数据获取的速度。

MySQL索引的类型:
MySQL的索引主要分为两种:
1、聚集索引(clustered index)
2、非聚集索引(non-clustered index)
聚集索引和非聚集索引的区别如下:
  1) 聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致,聚集索引表记录的排列顺序与索引的排列顺序一致,优点是查询速度快,因为一旦
具有第一个索引值的纪录被找到,具有连续索引值的记录也一定物理的紧跟其后。
  2) 聚集索引的缺点是对表进行修改速度较慢,这是为了保持表中的记录的物理顺序与索
引的顺序一致,而把记录插入到数据页的相应位置,必须在数据页中进行数据重排,
降低了执行速度。非聚集索引指定了表中记录的逻辑顺序,但记录的物理顺序和索引的顺序不一致,聚集索引和非聚集索引都采用了B+树的结构,但非聚集索引的叶子层并不与实际的

1、主键索引:主键索引是一种特殊的唯一索引,不允许有空值

2、普通索引或者单列索引

3、多列索引(复合索引):复合索引指多个字段上创建的索引,只有在查询条件中使用了创建索引时的第一个字段,索引才会被使用。使用复合索引时遵循最左前缀集合

4、唯一索引或者非唯一索引

5、空间索引:空间索引是对空间数据类型的字段建立的索引,MYSQL中的空间数据类型有4种,分别是GEOMETRY、POINT、LINESTRING、POLYGON。MYSQL使用SPATIAL关键字进行扩展,使得能够用于创建正规索引类型的语法创建空间索引。创建空间索引的列,必须将其声明为NOT NULL,空间索引只能在存储引擎为MYISAM的表中创建

如图:

CREATE TABLE table_name[col_name data type]
[unique|fulltext|spatial][index|key][index_name](col_name[length])[asc|desc]

1、unique|fulltext|spatial为可选参数,分别表示唯一索引、全文索引和空间索引;

2、index和key为同义词,两者作用相同,用来指定创建索引

3、col_name为需要创建索引的字段列,该列必须从数据表中该定义的多个列中选择;

4、index_name指定索引的名称,为可选参数,如果不指定,MYSQL默认col_name为索引值;

5、length为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度;

6、asc或desc指定升序或降序的索引值存储

总结

其实索引主要就是为了调整数据结构的,用合理的结构存储数据,以便于在获取数据的时候用更少的时间就能获取对应的数据。好了,完结。see you 啦啦。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐