Mysql索引--03---InnoDB中索引的推演

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


InnoDB中索引的推演

在这里插入图片描述

索引之前的查找

在这里插入图片描述
在这里插入图片描述

设计索引

1. 行格式设计

在这里插入图片描述
在这里插入图片描述
我们只在示意图里展示记录的这几个部分:

  • record_type
    记录头信息的一项属性,表示记录的类型( 0 表示普通记录、2 表示最小记 录、3 表示最大记录、1表示目录项记录的record_type 值)
  • next_record
    记录头信息的一项属性,表示下一条地址相对于本条记录的地址偏移量,我们用 箭头来表明下一条记录是谁。
  • 各个列的值
    这里只记录在index_demo 表中的三个列,分别是c1 、c2 和c3 。
  • 其他信息
    除了上述3种信息以外的所有信息,包括其他隐藏列的值以及记录的额外信息。
    在这里插入图片描述
    在这里插入图片描述

2. 一个简单的索引设计方案

Mysql 默认底层给每个节点(数据页)设置的容量大小是 16kb

在这里插入图片描述
在这里插入图片描述

3. InnoDB中的索引方案

① 迭代1次:目录项纪录的页

在这里插入图片描述
在这里插入图片描述

② 迭代2次:多个目录项纪录的页

在这里插入图片描述
在这里插入图片描述

③ 迭代3次:目录项记录页的目录页

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

④ B+Tree

计算一个h=3的b+树 能存多少个索引元素?

  • Mysql 默认底层给每个节点设置的容量大小是 16kb

在这里插入图片描述

  • 假设一个主键索引 类型为 bigint 8个字节,

  • Mysql 默认给指针分配的内存大小 是 6个字节

  • 每一个节点能存储 16*1024/(8+6)=1170个索引元素

  • 叶子节点的索引元素因为要存储data,所以按1kb的大小计算的话,一个叶子节点能存储16个索引元素

count(索引元素)=1170 * 1170 * 16=21902400

经过上述计算得知,一个高度h为3 的 B+树,叶子节点,大约能容纳2100万个索引元素.

所以上千万的数据表,MySQL也只要经过1到2次的io磁盘查找,就能获取到指定元素的数据.

常见索引概念

  • 索引按照物理实现方式,索引可以分为 2 种:聚簇(聚集)和非聚簇(非聚集)索引。我们也把非聚集 索引称为二级索引或者辅助索引。

1. 聚簇索引

B+树的叶子节点存储的是完整的用户记录

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 二级索引(辅助索引、非聚簇索引)

所有叶子节点,非主键索引关联的是 对应主键的值

在这里插入图片描述

回表

在这里插入图片描述
在这里插入图片描述

3. 联合索引

  1. 先把各个记录和页按照c2列进行排序。
  2. 在记录的c2列相同的情况下,采用c3列进行排序

在这里插入图片描述

在这里插入图片描述

4.InnoDB的B+树索引的注意事项

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

MyISAM中的索引方案

在这里插入图片描述
在这里插入图片描述

通过索引查找数据的流程:

  1. 先通过索引文件中查找到索引节点,
  2. 从中拿到数据的文件指针,再指针定位了具体的数据。

MyISAM 与 InnoDB对比

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

面试题

1. 为什么不建议使用过长的字段作为主键?

因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。

2. 为什么 InnoDB 上尽量采用自增字段做表的主键?

  • 因为 InnoDB 数据文件本身是一棵B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持 B+Tree的特性而频繁的分裂调整,十分低效,
  • 而使用自增字段作为主键则是一个很好的选择。如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页

如下图所示:
在这里插入图片描述

  • 这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很高,也不会增加很多开销在维护索引上。

3.为什么推荐使用整型自增主键而不是选择UUID?

  1. UUID是字符串,比整型消耗更多的存储空间;
  2. 在B+树中进行查找时需要跟经过的节点值比较大小,整型数据的比较运算比字符串更快速;
  3. 自增的整型索引在磁盘中会连续存储,在读取一页数据时也是连续;UUID是随机产生的,读取的上下两行数据存储是分散的,不适合执行where id > 5 && id < 20的条件查询语句。
  4. 在插入或删除数据时,整型自增主键会在叶子结点的末尾建立新的叶子节点,不会破坏左侧子树的结构;UUID主键很容易出现这样的情况,B+树为了维持自身的特性,有可能会进行结构的重构,消耗更多的时间。

4. 为什么InnoDB 非主键索引结构叶子节点存储的是主键值?

  • 保证数据一致性和节省存储空间,可以这么理解:商城系统订单表会存储一个用户ID作为关联外键,而不推荐存储完整的用户信息,因为当我们用户表中的信息(真实名称、手机号、收货地址···)修改后,不需要再次维护订单表的用户数据,同时也节省了存储空间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值