前言
前面已经写了有两篇章长度的文章,第三篇我一直在寻思着要写什么(其实并没有),按照脑图来的话,这篇文章我们该来讲讲关于索引的知识了,这可是 MySQL 性能优化很关键的知识点,千万千万不要错过,不过我这里会相对比较深入地探究,相信大家读完之后多少会有点收获。
先送上两张飞机票🛬还没读过前面文章的伙伴可以先前往阅读,由浅入深:
MySQL相关(一)- 一条查询语句是如何执行的
MySQL相关(二)- 一条更新语句是如何执行的
由于索引的知识点比较多,官网的内容也很多,如果大家想详细了解可以到官网,想先通读了解的话可以先看看我对索引的总结,这一章节分为三部分来讲:
- innodb 逻辑存储结构需要了解,作为番外篇
MySQL相关(番外篇)- innodb 逻辑存储结构; - 索引的数据结构也作为另外的篇章,通过对查询算法的数据模型进行演算分析
MySQL相关(三)- 索引数据模型推演及 B+Tree 的详细介绍; - 对索引的使用及优化规则也会作为单独的篇章
MySQL相关(四)- 性能优化关键点索引
前面提到的脑图如下,想要完整高清图片可以到微信我的公众号下【6曦轩】下回复 MySQL 脑图获取:
正文
innodb 逻辑存储结构
https://dev.mysql.com/doc/refman/5.7/en/innodb-disk-management.html https://dev.mysql.com/doc/refman/5.7/en/innodb-file-space.html
MySQL 的存储结构分为 5 级:表空间、段、簇、页、行。
表空间 Table Space
上一篇文章讲磁盘结构的时候提到过,表空间可以看做是 InnoDB 存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。分为:系统表空间、独占表空间、通用表空间、 临时表空间、Undo 表空间。
段 Segment
表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等,段是一个逻辑的概念。一个 ibd 文件(独立表空间文件)里面会由很多个段组成。
创建一个索引会创建两个段,一个是索引段:leaf node segment,一个是数据段:non-leaf node segment。索引段管理非叶子节点的数据。数据段管理叶子节点的数据。
也就是说,一个表的段数,就是索引的个数乘以 2。
簇 Extent
一个段(Segment)又由很多的簇(也可以叫区)组成,每个区的大小是 1MB(64个连续的页)。
每一个段至少会有一个簇,一个段所管理的空间大小是无限的,可以一直扩展下去,但是扩展的最小单位就是簇。
页 page
为了高效管理物理空间,对簇进一步细分,就得到了页。簇是由连续的页(Page)组成的空间,一个簇中有 64 个连续的页。 (1MB/16KB=64)。这些页面在物理上和逻辑上都是连续的。
跟大多数数据库一样,InnoDB 也有页的概念(也可以称为块),每个页默认 16KB。
页是 InnoDB 存储引擎磁盘管理的最小单位,通过 innodb_page_size 设置。
一个表空间最多拥有 2^32 个页,默认情况下一个页的大小为 16KB,也就是说一个表空间最多存储 64TB 的数据。
注意,文件系统中,也有页的概念。
操作系统和内存打交道,最小的单位是页 Page。文件系统的内存页通常是 4K。
SHOW VARIABLES LIKE 'innodb_page_size';
假设一行数据大小是 1K,那么一个数据页可以放 16 行这样的数据。
举例:一个页放 3 行数据。
往表中插入数据时,如果一个页面已经写完,产生一个新的叶页面。如果一个簇的所有的页面都被用完,会从当前页面所在段新分配一个簇。
如果数据不是连续的,往已经写满的页中插入数据,会导致叶页面分裂:
行 Row(仅供了解)
InnoDB 存储引擎是面向行的(row-oriented),也就是说数据的存放按行进行存放。
https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html
Antelope[ˈæntɪləʊp](羚羊)是 InnoDB 内置的文件格式,有两种行格式:
REDUNDANT[rɪˈdʌndənt] Row Format
COMPACT Row Format(5.6 默认)
Barracuda[ˌbærəˈkjuːdə](梭子鱼)是 InnoDB Plugin 支持的文件格式,新增了 两种行格式:
DYNAMIC Row Format(5.7 默认) COMPRESSED Row Format
文件格式 | 行格式 | 描述 |
---|---|---|
Antelope (Innodb-base) | ROW_FORMAT=COMPACT ROW_FORMAT=REDUNDANT | Compact 和 redumdant 的区别在就是在于首部的存 存内容区别。 compact 的存储格式为首部为一个非 NULL 的变长字 段长度列表 redundant 的存储格式为首部是一个字段长度偏移 列表(每个字段占用的字节长度及其相应的位移)。 在 Antelope 中对于变长字段,低于 768 字节的,不 会进行 overflow page 存储,某些情况下会减少结果 集 IO. |
Barracuda (innodb-plugin) | ROW_FORMAT=DYNAMIC ROW_FORMAT=COMPRESSED | 这两者主要是功能上的区别功能上的。 另外在行 里的变长字段和 Antelope 的区别是只存 20 个字节, 其它的 overflow page 存储。 另外这两都需要开启 innodb_file_per_table=1 |
innodb_file_format 在配置文件中指定;row_format 则在创建数据表时指定。
show variables like "%innodb_file_format%"; SET GLOBAL innodb_file_format=Barracuda;
在创建表的时候可以指定行格式。
CREATE TABLE tf1 (c1 INT PRIMARY KEY) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
查看行格式:
SHOW TABLE STATUS LIKE 'student' \G;
这一块的内容主要是让大家了解页 page 的概念。 接下来我们可以到MySQL相关(三)- 索引数据模型推演及 B+Tree 的详细介绍查看关于索引数据结构的演算。
By the way
有问题?可以给我留言或私聊
有收获?那就顺手点个赞呗~
当然,也可以到我的公众号下「6曦轩」,
回复“学习”,即可领取一份
【Java工程师进阶架构师的视频教程】~
回复“面试”,可以获得:
【本人呕心沥血整理的 Java 面试题】
回复“MySQL脑图”,可以获得
【MySQL 知识点梳理高清脑图】
由于我咧,科班出身的程序员,php,Android以及硬件方面都做过,不过最后还是选择专注于做 Java,所以有啥问题可以到公众号提问讨论(技术情感倾诉都可以哈哈哈),看到的话会尽快回复,希望可以跟大家共同学习进步,关于服务端架构,Java 核心知识解析,职业生涯,面试总结等文章会不定期坚持推送输出,欢迎大家关注~~~