MySQL InnoDB索引机制
前言
MySQL中索引的合理使用能够帮助MySQL高效地获取数据,MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构,索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。通俗来讲,索引类似文章的目录,用来提高查询的效率。
一、MySQL索引分类
1、主键索引
主键索引字段为表的主键,需保证非空且唯一,一个表只有一个主键索引。在innodb存储引擎中,逐渐索引的B+树存储数据信息。
PRIMATRY KEY(key1, key2)
2、唯一索引
唯一索引的字段约束为:保证唯一,相比主键索引不需要保证字段非空。字段值可以为NULL。
UNIQUE(key)
3、普通索引
普通索引字段允许字段值为NULL且允许出现重复的索引内容。
INDEX(key) -- OR KEY(key[,...])
4、组合索引
对表上的多个列创建索引。
INDEX idx(key1,key2[,...]); UNIQUE idx(key1,key2[,...]); PRIMARY KEY(key1,key2[,...]);
5、全文索引
将存储在数据库当中的整本书和整篇文章中的任意内容信息查找出来的技术;关键词 FULLTEXT;
在短字符串中用 LIKE %;在全文索引中用 主键选择 match 和 against。
二、MySQL innodb存储管理
在innodb存储引擎中数据由段、区、页组成,段分为数据段、索引段、回滚段等;区的大小为1MB(1个区由64个连续页组成);页的默认值为16K;页为逻辑页,磁盘物理页大小一般为4K或者8K;为了确保区中的页连续,存储引擎一般一次从磁盘中申请4~5个区。
页是innodb磁盘管理的最小单位;默认为16K,该参数可以通过innodb_page_size参数来修改。
在innodb存储引擎中创建数据表,其实际生成两个文件:xxx.ibd(表索引和数据文件)xxx.frm(表结构类型)。
其中ibd文件就是通过上述组织方式实现对表数据的划分以支持MySQL innodb存储方式的相关实现。
三、Mysql innodb数据组织方式
在innodb存储引擎中对表数据的组织方式选用B+树数据结构。对于MySQL而言,他的数据存储在硬盘中,其主要流程涉及到关系型数据的增删改查,因此对于数据的组织方式需要较高的查询效率。对于这种场景Hash、平衡二叉树、红黑树均可以实现且效率都不低。但是innodb选择B+树存储数据。主要原因如下:
1、MySQL数据存储在硬盘中,对于数据的查询主要通过数据比对,即对比客户端需求数据条件以及当前存储的数据,然后返回符合条件的数据。这样的场景下如果选择平衡二叉树或者红黑树,其对比过程需要逐层选择对应的叶子节点或者非叶子节点,此时每一层数据的获取都需要进行一次数据的获取也就涉及到一次硬盘IO。且对于上述两种数据结构存储数据的话,其树的树高也会较高,此时他的查询效率就受到硬盘IO的极大限制。而B+树是一颗多路平衡搜索树,且对比B+树他的非叶子节点并不存储具体的数据,而是存储Key值和下个节点的地址。这样非叶子节点可以存储更多的索引信息。这样B+树存储数据其最终形成的是一棵较为“矮 胖”的树。这样在搜索过程中其硬盘IO次数就会骤减。因此B+树更加适合。
2、对于MySQL的使用场景中,数据的范围查询也很多。而B+树的叶子节点位于同一层,并且叶子节点通过指针串联形成一个有序链表。因此在范围查询场景下,B+树的查询效率更好。反之其他数据结构还是需要在定位到一个范围区间后,再次从头开始逐层比对。而B+树可以通过链表指针获取范围查询所需数据。
四、innodb索引实现
1、聚集索引
聚集索引是根据表的主键构造的一颗B+树,其叶子节点存放数据页,即存放具体的数据行。
对于聚集索引,innodb存储引擎的数据表肯定会包含一个主键,主键可以通过PRIMERY KEY进行指定,如果未直接指定会从非空唯一索引中的选择第一个字段作为主键。如果没有非空唯一索引,则自动生成一个6字节的_rowid作为主键。
因此对于innodb存储引擎的数据表必定包含主键。聚集索引的非叶子节点是一个页,其中包含的数据信息是主键 + 该主键对应部分数据的指针,然后叶子节点会也是一个页,页中会包含大量数据行,具体组织方式通过存储主键 + 该数据行的其他字段信息。
2、辅助索引
辅助索引是又称为二级索引,除了聚集索引之外,其他所有的索引通过辅助索引方式实现。
对于辅助索引的实现,与聚集索引的区别就是在于叶子节点存储的value值不同,聚集索引的叶子节点中存储的KV键值对的value值是具体的数据行。而辅助索引存储的的value值是主键。在辅助索引命中后,会根据查找到对应的主键值后,返回聚集索引B+树中查询具体的数据行信息。这个过程也叫“回表”操作。
3、总结
在innodb中,每个表的数据通过一个B+树结构的聚集索引(由主键索引定义)来组织物理存储。除此之外,在该表中创建的所有其他索引(唯一索引、普通索引等),在物理存储上都是通过独立的B+树结构实现的二级索引(辅助索引),这些B+树的叶子节点存储的是该索引的列值以及对应数据行的主键值(聚集索引键)。
更多资料:0voice · GitHub