5. MySQL InnoDB的索引与优化

本文详细介绍了MySQL InnoDB的索引优化策略,包括重建索引以减少空洞、使用自增主键以避免页分裂、利用覆盖索引减少回表、优化回表操作如MRR和ICP,以及如何处理索引选择异常。建议在建立联合索引时考虑排序以减少排序操作,并指出在不影响业务逻辑的情况下,普通索引通常优于唯一索引。
摘要由CSDN通过智能技术生成

专栏地址:

MySQL系列文章专栏



1. 索引与表的维护

为什么要重建索引

索引树会因为删除、页分裂等原因,导致数据页有了空洞。重建索引会创建一个新的索引,将数据按顺序插入。使得,索引更加紧凑,数据页利用率更高。

场景

假设表T有索引k和主键索引id,依次使用drop 和add重新创建索引是否合适?

# 重建索引k
alter table T drop index k; 
alter table T add index(k);

# 重建主键
alter table T drop primary key; 
alter table T add primary key(id);

这种方式重建索引k是合适的,但是不适用于主键。无论删除主键还是创建主键,都会导致整个表重建,drop和add导致表重建了两次。正确的做法是使用alter table T engine=innoDB直接进行重建表。

表空间的回收

InnoDB对行记录的删除并不是真正的物理删除,而是对删除的行记录进行标记(delete falg),并将其占用空间放入PAGE_FREE列表中,以便后续复用。若整个页的记录都被删除掉了,则整个页都可以复用。

因此删除数据不会并使得表空间缩小,同时还会产生数据页空洞。若要对表空间进行收缩,可以使用alter table命令进行重建表。

2. 使用自增主键

追加插入,无页分裂

自增主键追加的插入模式,不会造成页分裂,也就不需要移动其它记录。

长度短

自增主键一般使用8字节的bigint,较业务主键长度更短:

  • 二级索引的叶子节点数据量更短,整体占用空间更少;
  • 聚集索引内部更加紧凑。

反例

KV场景,只有一个索引,该索引必须唯一。

3. 使用覆盖索引

3.1 回表

二级索引(辅助索引)的叶子节点保存的是聚簇索引,即主键。利用二级索引进行查询时,若不能获取到所有需要查询的字段,则需要一次额外的回表操作——得到主键之后,再到聚簇索引树中进行查找。

回表操作位于引擎层,Server层和引擎层的交互以行记录为单位。

SELECT * FROM t WHERE k BETWEEN 5 AND 7;需要执行几次树的搜索操作?

对K索引树执行了1次搜索操作,并依次读取了3、5、7三个值,对3、5进行了2次回表,搜索了2次聚集索引树。

3.2 利用覆盖索引减少回表

二级索引已经包含SELECT以及WHERE中所有的列时,称之为覆盖索引,此时不需要在进行回表操作。

覆盖索引能够显著提升性能,是一个常见的优化手段。对于高频的请求上建立覆盖索引,不需要再进行回表操作查询整行记录,减少语句的执行时间。

但是索引的维护也是有代价的,在建立冗余索引来支持覆盖索引时就需要权衡考虑

可以使用覆盖索引的典型场景有:

  1. 查询条件是主键,SELECT列是主键;
  2. 查询条件是联合索引,SELECT列是主键或者联合索引的部分列。

3.3 InnoDB对回表的优化

3.3.1 MRR(Mutil-Range Read)

为了减少回表时的随机IO,将其转换成较为顺序的磁盘读取,InnoDB查询二级索引得到主键后,在回表前会对主键先进行排序在进行回表。InnoDB并不是得到所有索引后在回表(减少不必要的额外存储),MRR只能减少回表的随机I

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值