MySQL - MySQL不同存储引擎下索引的实现

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: MySQL - MySQL不同存储引擎下索引的实现

20200719162059490.png

生猛干货

带你搞定MySQL实战,轻松对应海量业务处理及高并发需求,从容应对大场面试


Pre

MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,我们这里主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式。


MyISAM索引实现

非聚簇(非聚集)索引

我们建立一个myIsam存储引擎的表,看磁盘上的文件存储如下


20200719163410681.png


我这个是8.0的MYSQL, 5.7版本 不是sdi结尾的文件,而是frm (framework)


可以看到MyISAM存储引擎的索引文件 MYI 和数据文件 MYD 是分离的(非聚集)


这就是非聚簇索引的含义, MYI 和 MYD 分开存储 ,同样的 InnoDB都存在.idb文件中,所以InnoDB存储引擎的索引就是聚簇索引。


索引原理图


MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。



20200719164613769.png


上图就是 MyISAM索引的原理图。


上图一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件仅仅保存数据记录的地址


在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。


如果我们在Col2上建立一个辅助索引,则此索引的结构如下图所示:


20200719164704492.png

同样也是一颗B+Tree,data域保存数据记录的地址。


因此,MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,去另外一个文件中MYD读取相应数据记录。


MyISAM的索引方式也叫做“非聚集”的,之所以这么称呼是为了与InnoDB的聚集索引区分。


InnoDB索引实现


聚簇(聚集)索引


建立一个innodb存储引擎的表,看磁盘上的数据文件如下

20200719164201553.png


这个ibd就是 数据和索引,这两个存储在一个文件中


第一个重大区别是InnoDB的数据文件本身就是索引文件 ,因为就只有一个ibd文件啊。


MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。

InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。


InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM 不同。


索引原理图


20200719164902154.png


上图就是InnoDB主索引(同时也是数据文件)的示意图,可以看到叶节点包含了完整的数据记录。这种索引叫做聚集索引。

第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域


20200719164912977.png


上图为 定义在Col3上的一个辅助索引 观察叶子节点 : data域存储相应记录主键的值而不是地址


Col3字段上的索引,以英文字符的ASCII码作为比较准则。


聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后用主键到主索引中检索获得记录。


常见面试题


为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?


因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。


至于是整型,主要是构建B+Tree的时候,从左到右递增的属性,你如果用过UUID,不仅占用空间,还要转换成assic码进行比较,效率自然不行。


为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)


知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大,占用空间。


再比如用非单调(可重复)的字段作为主键在InnoDB中是不推荐的,因为InnoDB数据文件本身是一颗B+Tree,可重复的主键会造成在插入新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,十分低效,所以推荐使用自增主键。


参考 : http://blog.codinglabs.org/articles/theory-of-mysql-index.html


搞定MySQL

https://artisan.blog.csdn.net/article/details/107447007?spm=1001.2014.3001.5502

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
16天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
12 0
|
22天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
|
27天前
|
存储 自然语言处理 关系型数据库
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
38 0
|
27天前
|
SQL 存储 关系型数据库
MySQL not exists 真的不走索引么
MySQL not exists 真的不走索引么
24 0
|
16天前
|
SQL 缓存 关系型数据库
mysql性能优化-慢查询分析、优化索引和配置
mysql性能优化-慢查询分析、优化索引和配置
82 1
|
22天前
|
缓存 关系型数据库 MySQL
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
MySQL查询优化:提速查询效率的13大秘籍(合理使用索引合并、优化配置参数、使用分区优化性能、避免不必要的排序和group by操作)(下)
|
22天前
|
缓存 关系型数据库 MySQL
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
MySQL 查询优化:提速查询效率的13大秘籍(索引设计、查询优化、缓存策略、子查询优化以及定期表分析和优化)(中)
|
21小时前
|
存储 缓存 关系型数据库
MySQL 存储引擎
MySQL 存储引擎
14 6
|
12天前
|
存储 关系型数据库 MySQL
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
【4月更文挑战第9天】InnoDB数据库使用B+树作为索引模型,其中主键索引的叶子节点存储完整行数据,非主键索引则存储主键值。主键查询只需搜索一棵树,而非主键查询需两次搜索,因此推荐使用主键查询以提高效率。在插入新值时,B+树需要维护有序性,可能导致数据页分裂影响性能。自增主键在插入时可避免数据挪动和页分裂,且占用存储空间小,通常更为理想。然而,如果场景仅需唯一索引,可直接设为主键以减少查询步骤。
15 1
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
|
14天前
|
关系型数据库 MySQL 数据库
6. 了解过Mysql的索引嘛 ?
了解MySQL的索引类型,包括单列索引(普通、唯一、主键和全文索引)和组合索引。单列索引用于一列,如普通索引允许重复值,唯一索引和主键索引不允许,后者不允许空值。全文索引适用于特定文本字段。组合索引是多列的,遵循左前缀原则,通常推荐用于提高查询效率,除非是主键。
16 0