MySQL存储引擎与索引

27 阅读4分钟

存储引擎

SHOW ENGINES 命令来查看 MySQL 支持的所有存储引擎;

image.png

从上图可以看出, MySQL 当前默认的存储引擎是 InnoDB。并且所有的存储引擎中只有 InnoDB 支持事务。 MySQL 5.5.5 之前,MyISAM 是 MySQL 的默认存储引擎。5.5.5 版本之后,InnoDB 是 MySQL 的默认存储引擎。

MyISAM和InnoDB的区别?

MyISAMInnoDB
事务不支持提供事务支持,默认使用可重读隔离级别,可解决幻读问题发生。
锁级别仅支持表级锁,锁粒度太大,并发性能受限。默认行级锁,并发性能高,且支持手动更改表级锁。
外键不支持支持外键约束,但实际开发为避免外键带来的性能问题,会选择在业务代码中进行约束。
索引实现非聚集索引,索引(表名.MYI)和数据(表名.MYD)分开存储。聚簇索引,索引文件和数据文件同时存放在表名.ibd文件中。
异常恢复不支持支持数据库异常崩溃后的安全恢复,恢复的过程依赖于 redo log 。

索引

索引是一种用于快速查询和检索数据的数据结构,本质可以看成是一种排序好的数据结构。

索引是针对底层存储引擎的概念。不同的存储引擎对索引的支持和实现方式不同,服务器层在查询优化时会利用这些索引提高查询效率。

image.png

InnoDB中的索引类型

InnoDB存储引擎中,根据数据的存储形式不同,分为聚集索引非聚集索引两种形式。

聚集索引

将数据存储与索引放到了一块,索引结构的叶子节点保存行数据,数据按照主键的顺序存储。一张表中必须存在聚集索引,且只能有一个,InnoDB 中的主键索引就属于聚簇索引。

聚集索引选取规则:

  • 如果存在主键,主键索引就是聚集索引。
  • 如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。
  • 如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid字段,作为隐藏的聚集索引。
主键索引(Primary Key)

数据表中的主键列使用的就是主键索引。

非聚集索引

将数据与索引分开存储,索引结构的叶子节点关联数据行的主键

普通索引

在数据表的普通字段上建立的索引,称为普通索引。

唯一索引(UNIQUE)

为唯一列创建的索引。

联合索引

使用表中的多个字段创建索引,就是联合索引。

全文索引

只能在文本类型char,varchar,text类型字段上创建全文索引。

MySQL索引底层数据结构

MySQL中索引底层数据结构选取的是B+树,InnoDB默认缓存页大小为16KB(页在物理空间是不连续的,页与页之间通过指针链接),一个页可以视作B+树中的一个节点,意味着可以容纳16KB容量的数据值,到达16KB后会进行页分裂。

为什么选取B+树作为索引的底层结构?

B+树中,非叶子节点仅存储索引值和指向下个页的指针,而叶子节点存储行数据(主键索引)或主键值(普通索引),非叶子节点不用像B树一样存储大量行数据,则可以容纳更多的键值,降低整个树的高度,从而减少了与磁盘IO的次数,提升了查询效率。同时叶子节点是一个双向链表,范围查询时,找到边界值后顺序遍历叶子节点即可,范围查询效率更高

为什么不选择Hash或B树作为索引底层结构?

索引结构原因
Hash只支持等职查询,不支持范围查询。
B树由于每个节点都存储索引值和行数据,如果行数据占用空间较大,导致树的层级会较深,查询的效率便会降低。同时B树叶子节点独立,也不支持高效范围查询

B树

B树也称多路平衡查找树,每个节点的键值是由小到大排序,它的特点如下:

  • 所有节点同时存放索引值和行数据;节点中的索引值由小到大排序。
  • 叶子节点独立,因此范围查需要递归从根节点遍历查找,效率较低。

B+树

B+树是B树的一种变体,它的特点如下:

  • 叶子节点同时存储索引值和行数据
  • 非叶子节点仅存储索引值(下一页的最小索引值)和指向下个页的指针,索引值仅仅用于引导查找。
  • 所有叶子节点通过指针连接成一个有序链表,便于范围查询(找到边界值后只需要对链表进行遍历即可)。
  • 检索效率稳定,任何查找都是从根节点到叶子节点的过程。

B+树的结构示例图如下:

image.png