MySql中的索引及优化策略
MySql的存储层可以使用不同的存储引擎,不同的引擎存储支持的索引不同,实现索引的方式也不同,本文仅介绍InnoDB存储引擎支持的索引及其实现方式。
InnoDB存储引擎支持一下几种常见的索引:
这主要是基于B-树和B+树的结构不同,原因大致有如下几点:
我们以查找id为4的人员为例,根据根索引页Page3,知道应该取出关键字为1的右边的索引页Page4,然后根据Page4的索引知道应该取出数据页Page6,在数据页Page6中进行查询,取出id为4的人员信息。
InnoDB存储引擎支持一下几种常见的索引:
- B+树索引
- 哈希索引
- 全文索引
下面进行详细的介绍。
2.1 B+树索引
2.1.1 InnoDB为什么选择B+树作为索引
前面我们介绍了多种可以作为索引的数据结构,最后我们也知道为什么只有平衡多路搜索树适合作为索引。但平衡多路搜索树有B-树和B+树,那为什么InnoDB选择B+树呢?这主要是基于B-树和B+树的结构不同,原因大致有如下几点:
- 由于B+树在非叶子节点上不包含数据信息,则一个节点(一页)能够存放更多的关键字,则扇出dd更大。 因为B-树节点不仅存放了关键字作为树的索引信息,还存放关键字对应的数据记录的指针信息,而B+树非叶子节点只有关键字,最后一层的叶子节点有所有关键字对应的数据记录的指针信息,因此一个节点能够存放更多的关键字,则扇出dd更大。在同样的数据量nn的情况下,dd越大,则高度hh越小,则一次检索的磁盘I/0就小。
- B+树的叶子结点都是相链的,并且从小到大存放了所有的关键字,因此对整棵树的遍历只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B-树则需要进行每一层的递归遍历。相邻的元素可能在内存中不相邻,所以缓存命中性没有B+树好。
2.1.2 聚簇索引
在InnoDB中,每一个数据表都有一个聚簇索引,也称为主键。我们以如下的人员表 T 为例。create table T( id int primary key, age int, name varchar(16) )engine=InnoDB;其中id字段为聚簇索引,则该表的存储示意图如下。其中Page3和Page4为索引页,存放索引关键字,最后Page5到Page7为数据页,存放完整的行记录。
2.1.3 辅助索引
在InnoDB中,我们可以给数据表建立辅助索引,辅助索引也称非聚簇索引,我们在人员表 T 建立age的辅助索引,这索引的示意图如下。
辅助索引的数据页并不是包含对应的完整行记录,但为了能够找到完整的行记录,因此辅助索引的数据页存储了行记录的主键。通过这个主键,可以通过聚簇索引查找完整的行记录。
我们在人员表T上建立 (name,age)的联合索引,示意图如下。
我们以查age=30为例。通过根索引页Page3找到索引页Page4,然后索引到数据页Page6。在Page6中取出age为30的id为4,然后查找id=4的行记录。
聚簇索引和辅助索引有什么不同点:- 数据页存放的数据不同。聚簇索引的数据页存放的是完整的行数据,而辅助索引的数据页存放的是聚簇索引值,通过这个聚簇索引值可以找到完整的行记录。
- 查询模式不同。通过聚簇索引可以直接得到完整的行记录,但基于辅助索引的查找不能。基于辅助索引的查询为了得到完整的行记录,需要需要多扫描一棵索引树(聚簇索引对应的B+树),这称为回表。
2.1.4 联合索引
在人员表T中,我们建立了id字段的聚簇索引,建立了age字段的辅助索引,这都是在单个字段上建立索引,InnoDB还支持为多个字段建立索引,这就是联合索引。我们在人员表T上建立 (name,age)的联合索引,示意图如下。
和单个字段建立的索引不同,联合索引的数据页有多个关键字,如上图有name和age为关键字。数据先按name排序,相同的name按age排序,如上图的关键字顺序为 (Alice, 12) -> (Bob, 15) -> (
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
数据库索引-笔面试必考点15讲 文章被收录于专栏
Java开发之数据库索引篇,适合所有求职开发岗的同学~ 本专刊购买后即可解锁所有章节,故不可以退换哦~

