MySQL 性能调优专题一(索引数据结构详解)

本文围绕MySQL索引展开,介绍了索引本质是排好序的数据结构,默认用B+Tree。阐述磁盘读取原理,对比二叉树、红黑树、HASH索引和B+Tree的特点。还分析了MyISAM和InnoDB存储引擎的区别,讲解索引分类、优缺点及适用场景。

索引的本质

索引是帮助MySQL 高效获取数据的排好序数据结构

MySQL 默认使用的是B+Tree数据结构

磁盘的读取原理

在介绍结构之前,先简单说下磁盘的读取原理:

操作系统读写磁盘的基本单位是扇区,而文件系统的基本单位是簇(Cluster)。

MySQL在存储数据时数据都存储在磁盘的一道道扇区中,磁盘是旋转的,每次存储的数据可能会存储在不同的扇区中。

在读取时,磁道每次需要先进行寻道操作(速度慢),磁头只能进行左右移动,每一次寻道都是一次I/O操作。

如果数据都存在同一磁道中,那么旋转磁盘(速度快)就可以取到数据,不需要进行寻道操作,会大大减少开销。

这里是我自己的理解,如果有不对的地方,欢迎大家指出来

索引结构

给大家推荐一个数据结构可视化网站,可以直观的演示各种结构

二叉树

如果普通的一颗二叉树,在极端情况下会退化成链表结构。如图:

红黑树

和二叉树一样,在数据量大的情况下,树的深度太大,查询次数过高。

比如,有500W的数据,假如树的高度有20层,你要查询的数据刚好在叶子节点,那么需要进行20次寻道操作,和磁盘进行20次I/O交互操作,大大加大了开销。

HASH 索引

HASH索引,相比较于B-Tree 而言,不需要从根节点到叶子节点的遍历,可以一次定位到位置,查询效率更高,但缺点也很明显:

  • 仅能满足全值查询,不能使用范围查询。因为是通过HASH值进行计算,HASH值是没规律的,所以只能精确查询,不能保证顺序和原来一致,所以不行进行范围查询。

  • 不能进行排序,原因如上。

  • HASH碰撞。

B+Tree
  • B+Tree 是平衡树的一种,并且所有叶子节点位于同一层,是不会退化成链表结构的。

  • B+Tree 有一个的概念,指节点的数据存储个数。度越大,节点保存的数据个数就越多。那么相应的树的高度降低,在进行查询时,需要进行的I/O操作更少,读取数据的速度更快

  • 非叶子节点不存储data,只存储key,可以增大度。叶子节点只存储data, 不存储指针,顺序访问指针,可以提高区间访问的性能。

  • 进行查找操作时,首先在根节点进行二分查找,找到一个key所在的指针,然后递归的在指针所指向的节点进行查找。直到查找到叶子节点,然后在叶子节点上进行二分查找,找出 key 所对应的 data。

B+Tree 结构示意图

B+Tree 索引的性能分析
  • 一般使用磁盘I/O次数评价索引结构的优劣

  • 预读:磁盘一般会顺序向后读取一定长度的数据(页的整数倍)放入内存。

  • 局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。

  • B+Tree 节点的大小设为等于一个页,每次新建节点直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,就实现了一个节点的载入只需一次I/O。

  • B+Tree 的度一般会超过100,因此高度非常小(一般为3到5之间)

MySQL 存储引擎

MyISAM (非聚集)
  • MyISAM 索引文件和数据文件是分离的。

  • MyISAM 引擎使用B+Tree 作为索引结构,MyISAM的索引文件仅仅保存数据记录的地址

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

MyISAM存储结构示意图

InnoDB (聚集)
  • 数据文件本身就是索引文件

  • InnoDB 引擎也使用B+Tree 作为索引结构,叶节点包含了完整的数据记录

  • InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有)。

  • InnoDB中,主键索引包含了完整的数据记录,而辅助索引都引用主键作为data域

InnoDB存储结构示意图

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

MyISAM和InnoDB区别
  • 事物:InnoDB支持事务,可以使用 Commit 和 Rollback 语句。MyISAM不支持。

  • 并发:MyISAM 只支持表级锁,而InnoDB 还支持行级锁。

  • 外键:InnoDB 支持外键,MyISAM不支持。

  • 备份:InnoDB 支持在线热备份,MyISAM不支持。

  • 崩溃恢复:MyISAM 崩溃后发生损坏的概率比 InnoDB 高很多,而且恢复的速度也更慢。

  • 其它特性

  1. InnoDB是聚集索引,MyISAM是非聚集索引。

  2. InnoDB不保存表的具体行数,MyISAM用变量保存了整个表的行数。

  3. InnoDB不支持全文索引,MyISAM支持全文索引。

  4. MyISAM 支持压缩表和空间数据索引。

索引分类
索引分类
  • 主键索引:是一种特殊的唯一索引,不允许有空值。设定为主键后数据库会自动建立索引innodb为聚集索引。

  • 唯一索引:索引列中的值必须是唯一的,但是允许为空值

  • 单值索引:索引只包含单个列,但一个表中可以有多个单值索引

  • 复合索引:在表中的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,使用组合索引时遵循最左前缀原则。

  • 全文索引:只有在MyISAM引擎上才能使用,只能在CHAR、VARCHAR、TEXT类型字段上使用全文索引,在一堆文字中,通过其中的某个关键字等,就能找到该字段所属的记录行。比如有"怡红院、金凤楼"等等,可以 通过金凤楼,可能就可以找到该条记录。

  • 空间索引:只有在MyISAM引擎上才能使用,创建空间索引的列,必须将其声明为NOT NULL。空间索引是对空间数据类型的字段建立的索引,MySQL中的空间数据类型有四种,GEOMETRY、POINT、LINESTRING、POLYGON。在创建空间索引时,使用SPATIAL关键字

最左前缀原则
  • B+Tree 是按照第一个关键字进行索引,然后在叶子节点上按照第一个关键字、第二个关键字、第三个关键字…进行排序。使用复合索引的时候,会根据你的索引顺序,从左开始匹配。

  • 索引只能用于查找key是否存在(相等),遇到范围查询(>、<、between、like左匹配)等就不能进一步匹配了,后续退化为线性查找。

复合索引的底层存储结构

索引的优缺点

优点
  • 提高查询效率(降低IO使用率)。

  • 降低CPU使用率, 例如:...order by age desc,因为B+Tree 索引本身就是一个排好序的结构,因此在排序时可以直接使用。

缺点
  • 索引本身很大,实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用空间。

  • 索引会降低增删改的效率,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段, 都会调整因为更新所带来的键值变化后的索引信息。

  • 索引不是所有情况均适用:A. 少量数据 B.频繁更新的字段 C.很少使用的字段

需要建立索引的情况

  • 主键自动建立唯一索引。

  • 频繁作为查询条件的字段应该创建索引,WHERE 后面的语句。

  • 查询中与其它表关联的字段,外键关系建立索引。

  • 单键/组合索引的选择问题,who?在高并发下倾向创建组合索引。

  • 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度。

  • 查询中统计或者分组字段。

转载于:https://juejin.im/post/5ce4106d6fb9a07ed91196ad

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值