MySQL的索引—详细篇

MySQL索引

感悟:原本以为MySQL的索引很平淡无奇,直到被面试官问到心底发慌



1.MySQL基本知识

1.定义

定义:索引是一种特殊的文件,它包含着对数据表里所有记录的引用指针。索引是一种数据结构,索引的实现通常使用B树和B+树。更通常的来说,索引就相当于目录。

2.优缺点:

优点:
(1)可以大大加快数据的检索效率。
(2)通过使用索引,可以在查询过程中,使用优化隐藏器,提高系统的性能。

缺点:
(1)时间方面:创建和维护索引要耗费时间,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,会较低增删改的效率
(2)空间方面:索引要占用物理空间

2.聚簇索引和非聚簇索引

MySQL数据库中innodb存储引擎,B+树索引可以分为聚簇索引和非聚簇索引,两种索引内部都是B+树,聚簇索引的叶子节点存放着一整行数据。主键索引是一种聚簇索引,非聚簇索引都是辅助索引,像复合索引、唯一索引

1.聚簇索引

按照每张表的主键构造一棵B+树,同时叶子节点中存放的就是整张表的行记录数据,每张表只能拥有一个聚簇索引。

优点:
1)数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中
2)聚簇索引对于主键的排序查找和范围查找速度非常快

2.非聚簇索引

在聚簇索引上创建的索引是非聚簇索引,访问数据总是需要二次查找。非聚簇索引叶子节点存储的不再是行的物理位置,而是主键值。通过非聚簇索引首先找到主键值,再通过主键值找到数据行的数据页,再通过数据行中的Page Directory找到数据行。

3.索引的使用场景

1.where

可以尝试在一个字段未建立索引时,根据该字段的查询效率,然后建立索引(alter table 表名 add index (字段名))

2.order by

当我们使用order by将查询结果按照某个字段排序时,如果该字段没有建立索引,那么执行计划会将查询出的所有数据使用外部排序(将数据从硬盘分批读取到内存使用内部排序,最后合并排序结果),这个操作是很影响性能的,因为需要将查询涉及到的所有数据从磁盘中读到内存(如果单条数据过大或者数据量过多都会降低效率)

但是如果我们对该字段建立索引alter table 表名 add index(字段名),那么由于索引本身是有序的,因此直接按照索引的顺序和映射关系逐条取出数据即可。而且如果分页的,那么只用取出索引表某个范围内的索引对应的数据,而不用像上述那取出所有数据进行排序再返回某个范围内的数据。(从磁盘取数据是最影响性能的)

3.join

对join语句匹配关系(on)涉及的字段建立索引能够提高效率

4.索引覆盖

如果要查询的字段都建立过索引,那么引擎会直接在索引表中查询,而不会访问原始数据,这叫索引覆盖。因此我们尽可能的在select后只写必须要查询的字段,以增加索引覆盖率。

5.索引的类型

1.普通索引

最基本的索引,没有什么限制,允许在定义索引的列中插入重复值和空值
create index index_name on user(name);

2.唯一索引

索引列中的值必唯一,但是允许空值
Create unique index_name on user(name);

3.主键索引

MySQL中每张表一般都会有自己的主键,MySQL会在主键上建立一个索引。主键是具有唯一性且不允许为null

4.全文索引

主要用来查找文本中的关键字,而不是直接与索引中的值相比较。fulltext索引与其他索引大不相同,它更像是一个搜索引擎,而不是简单的where语句的参数匹配。正常情况下一般不会用到全文索引,因为这不是MySQL的专长

5.空间索引

是对空间数据类型的字段建立的索引,MySQL中空间数据类型有4种:geometry、point、lineString、polygon。
create spatial index index_name on user(name)

创建空间索引的列,必须将其声明为not null,空间索引只能在存储引擎为myisam的表中创建,空间索引一般用不到

6.复合索引

建立索引的时候可以使用多个字段,例如同时使用身份证和手机号建立索引,同样的可以建立为普通索引或者唯一索引
Create index index_name on user(name,id);

6.索引的数据结构

InnoDB默认索引实现为B+树。

哈希索引底层的数据结构就是hash表,因此绝大多数需求为单条记录查询的时候,可以选择哈希索引,查询性能最快,其余大部分场景选择BTree索引

1.B+树

底层实现原理:是一颗多路平衡查找树,对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据

1)B+树是有序的结构,为了不至于树的高度太高,影响查找效率,在叶子节点上存储的不是单个数据,而是一页的数据,提高了查找效率,并且叶子节点之间通过链表链接
2)B+树上有两个头指针,一个指向根节点,另一个指向关键字最小的叶子节点
3)B+树中,数据对象的插入和删除仅在叶子节点上进行

2.hash索引

hash索引底层就是hash表,进行查找的时候,调用一次hash函数就可以获取相应的键值,然后进行回表查询获得实际数据。(hash碰撞:两个不同关键字的hash值相同)

1)因为Hash索引比较的是经过Hash计算的值,所以只能进行等式比较,不能用于范围查询
2)由于哈希值是按照顺序排列的,但是哈希值映射的真正数据在哈希表中就不一定按照顺序排列,所 以无法利用Hash索引来加速任何排序操作
3)不能用部分索引键来搜索,因为组合索引在计算哈希值的时候是一起计算的。
4)当哈希值大量重复且数据量非常大时,其检索效率并没有Btree索引高的。

7.索引优化

1.选择索引列:可以考虑在where子句出现的列或join子句出现的列上建索引

2.最左前缀原则:B+树按照从左到右的顺序建立搜索树,因此B+树的数据结构决定了在使用索引的时候必须遵循最左前缀原则,在创建联合索引时,尽量将经常参与查询的字段放在联合索引的最左边。

3.一般不建议使用like:(like使用索引的情况,%在前面不会使用索引,中间或最后会用到索引。例如:like’%abc%’不会使用索引,like’aaa%’会使用索引)


Guess you like

Origin blog.csdn.net/weixin_48929324/article/details/118684672