mysql实战——深入浅出索引

六眼飞鱼酱① 提交于 2020-08-19 17:35:48

一、前言

       索引的出现就是为了提高数据查询的效率,就像书的目录一样。

二、索引常见数据结构

       可以用于提高读写效率的数据结构很多,常见的是哈希表、有序数组、搜索树。

       1、哈希表

       哈希表时一种key、value存储数据的结构,我们只要输入待查证的值即key,就可以找到其对应的值即value。哈希的思路很简单,把值放在数组里,用一个哈希函数把key换算成确定的值,然后把value放在数组的这个位置。多个key经过hash运算之后,会出现同一个值的情况。处理这种情况的一种方式是拉出链表。所以哈希表这种结构适用于只有等值查询(比如age=18)的场景,比如Memcached及其他一些NoSQL引擎。

       2、有序数组

       有序数组在等值查询和范围查询的场景中都非常优秀,如果仅仅看查询效率,有序数组就是最好的数据结构了。但是,在更新数据的时候就更麻烦了,你往中间插入一个记录就必须挪动后面所有的记录,成本太高。所以有序索引只适用于静态存储引擎。  比如2017年北京市所有出生人口信息,这类不会在修改的数据。

三、InnoDB的索引模型

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

       每一个索引对应一个B+树

       假设我们有1个主键列为ID的表,表中有字段K,并且在K上有索引。

       这个表的建表语句是:

mysql->create table t(
id int primary key,
k  int not null,
name varchar(16),
index(k))engine=InnoDB;

       表中R1~R5的(ID,K)   的值分别为(100,1),(200,2),(300,3),(400,4),(500,5),(600,6)。两棵树的示例示意图如下:

                        

       从图中可以看出,根据叶子节点的的内容,索引类型分为主键索引和非主键索引

       主键索引的叶子节点存的是整行数据,在InnoDB中,主键索引也被称为聚簇索引

       非主键索引的叶子节点存的是主键的值,在InnoDB中,非主键索引也被称为二级索引。

       基于主键索引和普通索引的查询有什么区别? 

       如果语句是select * from T where ID=500,即主键查询方式,则只需要搜索ID这颗B+树;如果语句是select * from T where K=5,即普通索引查询方式,则需要先索引k索引这棵树。得到ID的值为500,再到ID索引树搜索一次,这个过程称为回表。 也就是说基于非主键索引的查询需要多扫描1颗索引树。因此,我们在应用中,应该尽量使用主键查询。

四、回表和覆盖索引

mysql> create table T(
ID int primary key,
k int NOT NULL DEFAULT 0,
s varchar(16) NOT NULL DEFAULT '',
index k(k))
engine=InnoDB

insert into T values(100,1'aa'),(200,2'bb'),(300,3,'cc'),(400,4,'dd'),(500,5,'ee'),(600,6,'ff'),(700,7,'gg'),(800,8,'hh');

      1、回表 

      在上面这个表T中,如果执行select * from T where k between 3 and 5,需要执行几次树的索引操作,会扫描多少行。

                             

 

1、在k索引树上找到k=3的记录,取得ID=300;
2、再到ID索引树查到ID=300对应的R3;
3、在k索引树取下一个值k=5,取得ID=500;
4、再回到ID索引树查到ID=500对应的R4;
5、在k索引树取下一个值k=6,不满足条件,结束。

在这个过程中,回到主键索引树搜索的过程,我们称为回表。可以看到,这个查询过程中读了k索引树的三条记录(步骤1、3和5),回表了2次。(步骤2和4)

      2、覆盖索引

      如果执行的语句是select ID from T where k between 3 and 5。这时只需要查询ID的值,而ID的值已经在K索引树上了。因此可以直接提供查询结果,不需要回表。 也就是说在这个查询里面,索引k已经覆盖了我们的需求,所以我们称为覆盖索引。由于覆盖索引可以减少树的搜索次数,显著提高查询性能,所以使用覆盖索引是1个常用的性能优化手段

        

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!