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中可以获得的值就越多。
如果不在or<>中,面对B+树,引擎不知道从哪个节点开始。
不需要查询无用的字段,如果不使用*,可能会命中覆盖索引;
最左匹配原则;
感谢您仔细阅读本文。希望小编分享的mysql中innodb索引的原理对大家有所帮助。也希望对大家有所帮助。感谢您的支持,关注行业信息频道,遇到问题及时查找。详细解决方案等你学习!
2. 本站积分货币获取途径以及用途的解读,想在本站混的好,请务必认真阅读!
3. 本站强烈打击盗版/破解等有损他人权益和违法作为,请各位会员支持正版!
4. 编程技术 > mysql中innodb索引的原理是什么