Mysql索引--03---InnoDB中索引的推演
Posted 高高for 循环
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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. 联合索引
- 先把各个记录和页按照c2列进行排序。
- 在记录的c2列相同的情况下,采用c3列进行排序
4.InnoDB的B+树索引的注意事项
MyISAM中的索引方案
通过索引查找数据的流程:
- 先通过索引文件中查找到索引节点,
- 从中拿到数据的文件指针,再指针定位了具体的数据。
MyISAM 与 InnoDB对比
面试题
1. 为什么不建议使用过长的字段作为主键?
因为所有辅助索引都引用主索引,过长的主索引会令辅助索引变得过大。
2. 为什么 InnoDB 上尽量采用自增字段做表的主键?
- 因为 InnoDB 数据文件本身是一棵B+Tree,非单调的主键会造成在插入新记录时数据文件为了维持 B+Tree的特性而频繁的分裂调整,十分低效,
- 而使用自增字段作为主键则是一个很好的选择。如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页。
如下图所示:
- 这样就会形成一个紧凑的索引结构,近似顺序填满。由于每次插入时也不需要移动已有数据,因此效率很高,也不会增加很多开销在维护索引上。
3.为什么推荐使用整型自增主键而不是选择UUID?
- UUID是字符串,比整型消耗更多的存储空间;
- 在B+树中进行查找时需要跟经过的节点值比较大小,整型数据的比较运算比字符串更快速;
- 自增的整型索引在磁盘中会连续存储,在读取一页数据时也是连续;UUID是随机产生的,读取的上下两行数据存储是分散的,不适合执行where id > 5 && id < 20的条件查询语句。
- 在插入或删除数据时,整型自增主键会在叶子结点的末尾建立新的叶子节点,不会破坏左侧子树的结构;UUID主键很容易出现这样的情况,B+树为了维持自身的特性,有可能会进行结构的重构,消耗更多的时间。
4. 为什么InnoDB 非主键索引结构叶子节点存储的是主键值?
- 保证数据一致性和节省存储空间,可以这么理解:商城系统订单表会存储一个用户ID作为关联外键,而不推荐存储完整的用户信息,因为当我们用户表中的信息(真实名称、手机号、收货地址···)修改后,不需要再次维护订单表的用户数据,同时也节省了存储空间。
以上是关于Mysql索引--03---InnoDB中索引的推演的主要内容,如果未能解决你的问题,请参考以下文章