mysql中innodb索引的原理是什么

分类:编程技术 时间:2024-02-20 15:19 浏览:0 评论:0
0
本文主要介绍mysql中innodb索引的原理。有一定的参考价值。有需要的朋友可以参考一下。希望您读完这篇文章后能有所收获。让小编带你一起来了解一下吧。

聚集索引(clustered index)

Innodb存储引擎表是一个索引组织的表,表中的数据按照主键顺序存储。聚集索引按照每个表的主键顺序构建一棵B+树,它的叶子节点存储整个表的行记录数据,这些叶子节点成为数据页。 (相关推荐:MySQL教程)

聚集索引的存储不是物理上连续的,而是逻辑上连续的。叶子节点按照主键的顺序排序,并通过双向链表连接。大多数情况下,查询优化器倾向于使用聚集索引,因为聚集索引可以直接在叶节点查找数据,而且因为聚集索引的逻辑顺序f数据被定义后,可以非常快速地访问范围值的查询。

聚集索引的这一特性决定了索引组织表中的数据也是索引的一部分。由于表中的数据只能按照B+树排序,因此一张表只能有一个聚集索引。

在Innodb中,聚集索引默认为主键索引。如果没有主键,则按照以下规则构建聚集索引:

当没有主键时,将使用一个非空且唯一的索引列作为主键,成为该索引的聚集索引桌子;如果没有这样的索引,InnoDB 隐式地将主键定义为聚集索引。

由于主键采用聚集索引,如果主键是自增ID,则对应的数据会在磁盘上相邻存储,写入性能会很高。如果是uuid等字符串形式,频繁插入会导致innodb频繁插入过多地移动磁盘块,写入性能会比较低。

B+树(多路平衡搜索树)

我们知道innodb引擎索引采用B+树结构,那为什么不采用其他类型的树结构,比如二叉树呢?

计算机在存储数据时,有一个最小的存储单位,就像人民币流通的最小单位是分一样。文件系统的最小单位是块。块的大小为4K(该值根据系统不同,可以设置)。 InnoDB存储引擎也有自己的最小存储单位——页(Page)。一个页面的大小是16K(这个值也是可配置的)。

文件系统中一个文件的大小只有1个字节,但却要占用磁盘4KB的空间。同理,innodb中所有数据文件的大小始终是16384(16k)的整数倍。

所以在MySQL中,一个存储索引的块节点占用16K,MySQL的每次IO操作都会使用系统的re一次加载 16K 的广告提前能力。所以如果这个节点上只放一个索引值是非常浪费的,因为一次IO只能获取到一个索引值,所以不能使用二叉树。

B+树是一种多路径搜索树。一个节点可以保存n个值,n=16K/每个索引值的大小。
例如,如果索引字段大小为1Kb,那么每个节点理论上可以存储16个索引值。这种情况下,二叉树每个IO只能加载1个索引值,而B+树可以加载16个。

B+树的路数为n+1,其中n为路数每个节点中存在的值。例如,每个节点存储16个值,则树有17个路。

从这里也可以看出,B+树节点可以存储多个值,因此B+树索引无法找到给定键值的特定行。 B+树只能找到存储数据行的具体页,然后将该页读入内存,然后查找具体的页内存中的 ied 数据。

附:B树和B+树的区别在于B+树的非叶子节点只包含导航信息,不包含实际值。所有叶子节点和连通节点都使用链表连接,方便Range搜索和遍历。

辅助索引

也称为非聚集索引,它的叶子节点不包含行记录的全部数据。除了键值之外,每个叶子节点中的叶子节点索引行还包含一个书签,它是对应行的聚集索引键。

下图可以展示辅助索引和聚集索引的关系(图片来自网络,只看大概意思):

< p>当使用辅助索引来查找数据时,innodb存储引擎会通过辅助索引叶子节点获取只想主键索引的主键,然后查找通过主键索引获取完整的行记录。

例如,要在高度为3的辅助索引树中查找数据,则需要对辅助索引树执行3次IO才能找到指定的主键。如果聚集索引树的高度也是3,那么仍然需要对辅助索引树进行IO来查找指定的主键。需要对聚集索引树进行3次搜索才能最终找到完整行数据所在的页,因此总共需要6次IO访问才能得到最终的数据页。

创建的索引,如联合索引、唯一索引等,都是非聚集索引。

联合索引

联合索引是指对表的多个列建立索引。联合索引也是一棵B+树。不同的是,联合索引中键值的个数不是1,而是大于等于2。

比如有一个user表,字段有id、age、name 。发现以下两条 SQL 是最常用的:

Select * from user where age = ? ;从年龄 = ? 的用户中选择 * and name = ?;

此时就不需要为age和name建立两个单独的索引了。只需要建立以下联合索引即可:

 create index idx_age_name on user(age, name)

联合的另一个好处索引是第二个键值已经排序,有时可以避免额外的排序操作。

覆盖索引

覆盖索引是指可以从辅助索引中获取查询所需的所有字段值,而无需查询聚集索引中的记录。覆盖索引的优点是辅助索引不包含整行记录的所有信息,因此其大小比聚集索引小很多,因此可以减少大量的IO操作。

例如,有一个上面的联合索引(age, name),如果如下:

selectage, name from user where age=? 

您可以使用覆盖索引。

覆盖索引的另一个好处是解决统计问题,例如:

select count(*) from user
< p>innodb存储引擎不选择查询聚集索引进行统计。由于用户表上有辅助索引,并且辅助索引比聚集索引小得多,因此选择辅助索引可以减少IO操作。

注意事项

只构建合适的索引,不要构建冗余的索引
因为每次添加或删除数据时,B+树都要进行调整。如果创建了多个索引,多个B+树 都必须进行调整,而且树越多、结构越大,这种调整就越耗时、耗资源。如果减少这些不必要的索引,k的使用量可能会大大减少。
索引列的数据长度可以尽可能小。

索引数据长度越小,每个块中存储的索引就越多,一次IO中可以获得的值就越多。

匹配的列前缀可以在索引中使用like 9999%,like %9999%,like %9999不能使用索引; Where 条件中的 in 和 or in 可以使用索引,但 not in 和 <> 操作不能使用索引。 ;

如果不在or<>中,面对B+树,引擎不知道从哪个节点开始。

匹配范围值,order by也可以用来索引;使用指定列查询只返回你想到的数据列,谨慎使用select *;

不需要查询无用的字段,如果不使用*,可能会命中覆盖索引;

在联合索引中,如果不是从索引的最左列开始搜索,则该索引无法使用;

最左匹配原则;

联合索引中,可以利用索引精确匹配最左边的列,并匹配范围内的另一列;在联合索引中,如果查询中存在某个列的范围查询,则其右侧的所有列都无法被索引

感谢您仔细阅读本文。希望小编分享的mysql中innodb索引的原理对大家有所帮助。也希望对大家有所帮助。感谢您的支持,关注行业信息频道,遇到问题及时查找。详细解决方案等你学习!

1. 本站所有资源来源于用户上传或网络,仅作为参考研究使用,如有侵权请邮件联系站长!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > mysql中innodb索引的原理是什么

用户评论