简介
所有关于Mysql数据库优化的介绍仿佛都有存储引擎的身影。本文介绍Mysql常用的有MyISAM存储引擎和Innodb存储引擎,还有常见的索引。
Mysql有两种常见的存储引擎,MyISAM和Innodb,它们各有优劣,经过多次优化和迭代,现在常用的一般是Innodb引擎,因此MyISAM仅作基本介绍。
Innodb存储引擎
B+树结构
Mysql默认采用B+树存储结构,MyISAM也是采用B+树存储结构。然而,两者的不同在于,Innodb的叶子结点存储的数据,而MyISAM的叶子结点存储的索引。
聚簇索引和非聚簇索引
由于Innodb的叶子结点存储的实际数据,叶子结点又是B+树索引结构的一部分,因此这种将数据和索引结合起来的结构,我理解为聚簇索引。而没有将实际数据和索引结构结合起来的索引,理解为非聚簇索引。
聚簇索引: 实际数据是索引结构的一部分
非聚簇索引:实际数据不是索引结构的一部分
虽然MyISAM存储引擎也是B+树数据结构,但其叶子结点存储的数据地址,因此它属于非聚簇索引。
回到Innodb,由于实际数据是索引结构的一部分存储于物理介质之中,因此聚簇索引是唯一的,对于Innodb而言,一般主键索引是聚簇索引,如果未设置主键索引,为了保证Innodb的聚簇索引结构会自动生成主键。
主键索引与辅助索引
索引可以分为主键索引和辅助索引(二级索引)。
主键索引:主键索引的要求就是key的唯一性,对于Innodb而言是聚簇索引,对于MyISAM而言是非聚簇索引。
辅助索引:辅助索引都是非聚簇索引,因为这些索引都不包含实际的数据,只存储部分列值。它可以包含一列或多列,字符串前缀等等。
辅助索引的原理是将部分列重新构建为一个新的B+树结构,其叶子结点存放主键的ID,然后再通过主键ID回到主键索引中寻找实际的行数据,这个过程称为回表,从逻辑过程上来看,辅助索引一般情况下会查询两次B+树,其耗时会更长,因此在辅助索引优化过程中需要尽量减少回表次数。
如何减少回表次数?
是的,辅助索引的优化原则之一就是尽量减少回表次数,如果要减少回表次数就需要增加辅助索引的命中率。
根据辅助索引的特性,可以分为:
普通索引
联合索引
覆盖索引
前缀索引
-
普通索引和前缀索引
之所以将它们放在一起,是因为它们具有共性。前缀索引是通过截取字符串前N个字符构成一个索引,普通索引是通过单列来构成。在构造这类索引时都需要考虑:每个索引数据的强唯一性
这样才能保证辅助索引命中率更高,回表次数更少。
-
联合索引
普通索引和前缀索引都是通过单列数据来构建,而联合索引通过多列数据来构建。由于是多个列共同构建的索引,因此它的结构如下:最左匹配原则: Mysql一直向靠右的列匹配,直到遇到范围查找(like、>、<、between)时停止。
如果要弄清最左匹配原则,需要明白联合索引的查找原理。
联合索引的查找原理:
联合索引构建时会生成一颗B+树,这颗B+树是有序的,它的排序规则为:
左侧排序优先,当左侧相同时再排右侧。
- 覆盖索引
如果查询的列值已经可以通过辅助索引得到,则不需要回表,这个称为覆盖索引。
单列索引和联合索引都可以建立成覆盖索引。
B+树与Innodb的存储结构
B+树是Mysql底层的数据结构,其分为叶子结点和非叶子结点,最底层为叶子结点,上层为非叶子结点。通过从上至下的不断二分查找来快速定位。B树又称为Balanced Tree,属于平衡二叉树。
由于B树只具备随机查找特性,不具备连续查找特性,因此在B树上衍生出了B+树,其底层为双向链表。
当进行查询时,双向链表提供了顺序查询的基础。叶子结点和非叶子结点属于页结构,除了页结构,还有行、区、段、表空间等等。
存储结构由外到内:
表空间 -> 段 -> 区 -> 页 -> 行
页是内存与磁盘交互的最小单位,16KB。 也就是说Innodb内存每次最少取一个叶子结点的数据,然后在内存中操作。
叶子结点中的页属于数据页。
explain关键字
通过explain关键字可以实现查询优化,explain关键字将会给出所列sql的执行信息,包括
id:语句执行顺序的序号
key:索引名称,如果为null,则没有索引
type: 访问类型,常见值有system、const、ref、range、index、all
rows: 扫描的行数
通过以上一些指标可以检测当前的sql语句执行效率如何。
MyISAM
MyISAM由于不支持事务、不支持行级锁、不支持数据容灾等特点,它更多适用于查询较多的情况。
它是非聚簇索引,叶子结点存放物理地址。拿到物理地址后再去数据堆里取数据。它的存储结构如下:
MYD: 存放实际数据
MYI: 存放索引结构
FMI: 存放表定义等