mysql - 第1课 - 索引

一. 索引定义

索引是排好序的数据结构。

二. 索引的数据结构

mysql索引可选两种数据结构:B+树和hash。默认B+树。

索引为啥不用二叉树、红黑树?

二叉树和红黑树的节点只能存一个值,数据量大的时候树太高,检索的时候每个节点都需要进行一次io,io浪费性能。

image.png

B+树每个节点能存储16k(默认是16K,可以使用innodb_page_size参数修改),大概能存储1000多个值,能降低树高度,减少io次数。

指针大小大概占用6Byte

B+树B-树的区别

B-树:

image.png

B+树:

image.png

B+树的非叶子节点不存数据,叶子节点存数据;B-树在每个节点存了行数据的磁盘地址。

B+树把所有节点都放到叶子节点用链表连起来,方便范围查询(冗余叶子节点);B-树没有冗余叶子节点。

hash索引

image.png

hash索引的数据结构和jdk1.7的hashMap类似,由数组和链表组成。把字段值换算成hash码存入数组,有hash冲突时改成链表。

hash索引的优点:查找快,只用一次hash计算就能在数组匹配到值。

缺点:不能范围查询,不能模糊查询。

三. 索引的分类(InnorDB引擎)

索引分为主键索引(又叫聚簇索引)和非主键索引。非主键索引包括:普通索引、唯一索引、组合索引。

1.主键索引

image.png

主键索引非叶子节点中存储了主键的值,在叶子节点中保存了整行数据。查找的时候通过主键查找,找到在叶子节点找到整行数据。

非主键索引非叶子节点中存储索引的值,查找的时候通过索引的值进行查找,找到最后的叶子节点,叶子节点存储了对应的主键ID,然后根据查到的主键ID,从主键索引的B+树进行查找,直到找到这一行的所有数据。通过非主键索引找到主键,再通过主键索引找到整行数据的过程,称为回表

注意:每张表都有一个主键索引,当没设置主键的时候,mysql会把第一个不包含NULL值的唯一索引列作为主键索引。如果没有这样的列,就把行号作为主键索引。

2.组合索引

image.png

2.1最左前缀

全值匹配查询:查询条件全符合组合索引字段。

最左前缀查找:查找条件符合组合索引的最左边几项,索引就会生效。最左前缀可以是组合索引的最左边n个字段,也可以是字符串索引的最左边n个字符(例:like 'abc%')。

2.2 索引下推

例:建name,age 组合索引

select * from user where name like "B%" and age = 30;

mysql会以名字为“B”开头的数据开始遍历,然后判断年龄是否为30。

但是最左前缀有一个非常重要的原则:MySQL会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配。

所以此时这里的查询age索引用不上。

mysql5.6之前,只要找到了符合以“B”开头的名字这个条件,就会通过这个数据的主键ID,进行回表的操作,然后查找这个数据的年龄是否为30。

而MySQL 5.6 引入的索引下推优化(index condition pushdown), 可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。也就是说,直到找到了以“B”开头的名字并且年龄为30,才会进行回表。

此外,在回表之前,如果使用了Multi-Range Read (MRR)这个策略,在取出主键后,回表之前,会再对所有获取到的主键排序。

3.3 覆盖索引

查询字段已经被包含在了索引字段里,这样就不用回表。例如把name,age建了索引,查询字段只包含name,age字段。

3.唯一索引与普通索引

image.png

唯一索引和普通索引在叶子节点存储索引值和主键值。

唯一索引与普通索引区别:    

1.普通索引找到数据后继续往后遍历查找,直到找不到为止。唯一索引找到数据立刻返回。

2.唯一索引insert数据的时候会检验一次有没有重复,普通索引不会检验。

建议:业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。不要以为唯一索引影响了insert速度,这个速度损耗可以忽略,但提高查找速度是明显的;另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,根据墨菲定律,必然有脏数据产生。

四. InnorDB索引和MyISam索引的区别

注意数据库引擎是用来修饰表的,不是用来修饰数据库的。

上面有说到InnorDB的主键索引和非主键索引,都是在非叶子节点存储索引值,叶子节点存储索引值和数据,主键索引的数据是整行数据,非主键索引的数据是主键索引值。

这里介绍MyIsam引擎的索引。

MyIsam也是使用B+Tree作为索引结构,但是没有主键索引。非叶子节点存储索引值,叶子节点存储索引值和数据,数据保存的是数据文件的磁盘地址指针。

五. 索引是怎么找到数据的

MyIsam和InnorDb两种引擎用索引找数据的方式不一样。

1.MyIsam

MyIsam引擎的B+树每个节点存储了索引值和行数据的磁盘地址,找到索引后,用磁盘地址去磁盘文件找到数据。

数据以文件的形式存储在磁盘,例如磁盘目录:mysql/data/tablename

mysql/data/tablename/

*.frm    frm是frame的简写,存储的是表结构。

*.MYD    MYIsam Data的缩写,存储数据。

*.MYI    MYIsam Index的缩写,存储索引。

2.InnorDB

整行数据存储在聚簇索引的叶子节点上,通过聚簇索引,找到叶子节点就能找到整行数据。

六. 为什么建议把索引建成整形自增的

1.索引需要排序,如果是字符串,需要把字符串的每个字符转成ASCII码逐个比较进行排序。

2.整形自增的添加到索引树的时候只用在索引树后面追加即可,可以避免索引树自动调整。

猜你喜欢

转载自blog.csdn.net/qq_33743572/article/details/107716438