MySQL--索引

索引

索引是为了提高数据查询的效率,就类似与书的目录。

索引的常见模型

哈希表,也就是KV类型的结构,输入K即可得到相应的值,思路就是把值放到数组里,用一个哈希函数把K换成一个位置,然后在这个位置上找寻value。当不同的K经过换算有相同的结果是,采用拉链法。如下图:

 在这个图中,倘若K换算后的值得到的N,那么目标就是N位置后面的链表的某一个。采用顺序查找。用哈希表查询等值很快,但是缺点是不能进行范围查询。

有序数组,相比于哈希表,有序数组的好处就是可以进行范围查询,同时,用二分的话,等值查询的性能也可以很好的保证。但是,有序数组的缺点就是只适合静态存储引擎。

二叉搜索树,根据二叉树的特点(左孩子小于父节点,右孩子大于父节点),可以很容易来搜索树中的某个值,但是二叉搜索树在一些情况下会出现左右高度不平衡,所以需要保持一颗二叉平衡树,这样查询的复杂度是O(logN),更新一个结点也是O(logN)。

但是实际上二叉树是很少使用的,原因无他,结点数量过多的情况下,二叉树的高度也增加,访问磁盘的次数也会增加,从而查询变慢,所以引入了N叉树,N的值取决于数据块点大小。

InnoDB的索引模型

InnoDB中,表都是根据主键顺序以索引的形式来存放的,使用B+树来存储。

每一个索引都对应有一个B+树,比如建立一个表并设置一个索引,


CREATE table t6(
id int PRIMARY KEY,
k int not null,
name varchar(20),
INDEX (k)
)ENGINE=INNODB;

在这个例子中有两个索引,一个是主键索引,一个是K,每个索引都有一颗B+树。

现在向表中插入(ID,K)的值:(100,1),(200,2),(300,3),(500,5),(600,6)

则此时两颗树的结构如下图:

该图中,主键索引的叶子结点保存整行数据,非主键索引即K,叶子结点存储主键的值。

那么此处有两个查询方式,一种是根据主键索引查,一种是根据非主键索引,两者的区别在于:

如果是主键查询,则只需搜索ID的B+树,而如果是非主键查询,则需要先根据K查询到主键,再回表到ID的索引树,再查询信息。所以在项目中应该尽量使用主键查询来减少回表次数。

 那么怎么可以经过索引优化来避免回表呢?

覆盖索引

 假设现在执行:

SELECT ID FROM t6 where k BETWEEN 3 and 5;

这时候只需要查询ID,因为ID的值已经在K索引的树上了,所以可以直接提供结果而不需要回表,在这个查询里,索引K覆盖了查询请求,故也称之为覆盖索引。

 最左前缀原则

简单来说,就是在联合索引中,就是从左边的字段开始匹配。如采用(name,age)建立联合索引,那么就会有下图:

这里只要满足最左前缀原则,在这里可以查name,也可以name和age一起查,这个时候MySQL都会采用这个索引来查找。

 最左前缀原则如何安排字段的顺序:第一原则就是通过这样的调整,可以少维护一个索引,那么这个字段顺序是优先考虑使用的,第二个原则是空间,能节省空间的也是优先考虑的。

索引下推

当已经建有这样的联合索引但是查询却不是不符合最左前缀时,MySQL就会进行下推优化,对索引中包含的字段先进行判断,过滤掉不满足的条件,减少回表的次数,这显然比扫描全表要好。

原文地址:https://www.cnblogs.com/Yintianhao/p/12297631.html