MySQL 04 深入浅出索引(上)

索引的常见模型

实现索引的方式有很多种,这里先介绍三种常见结构:哈希表、有序数组和搜索树。

哈希表:只适用于只有等值查询的场景。

有序数组:在等值查询和范围查询场景中的性能都非常优秀,但是在更新数据的时候需要挪动大量记录。因此,只适用于静态存储引擎

二叉搜索树:树层数可能很高,可能一个节点上的数据在一个物理数据块上,那么访问叶子节点的数据需要大量磁盘IO。

为了让一个查询尽量少进行磁盘IO,使用N叉树代替二叉树。

数据库技术发展至今,跳表、LSM树等结构也被用于引擎设计中。需要明白的是,数据库底层存储的核心就基于数据模型,因此每碰到一个新数据库,需要先关注它的数据模型,这样才能从理论上分析出这个数据库的适用场景。

InnoDB的索引模型

在InnoDB中,表都是根据主键顺序以索引的形式存放的。由于InnoDB使用了B+树索引模型,所以数据都是存储在B+树中的。

每一个索引在InnoDB里对应一棵B+树。

根据叶子节点的内容,索引类型分为主键索引和非主键索引:

  • 主键索引的叶子结点存的是整行数据。在InnoDB里,主键索引也被称为聚簇索引。

  • 非主键索引的叶子结点存的是主键的值。在InnoDB里,非主键索引也被称为二级索引。

对于非主键索引,假设查询select *,那么需要先查询非主键的索引树,得到主键后再查询一次,这个过程称为回表。因此,应该尽量使用主键查询。

索引维护

B+树为了维护索引有序性,在插入新值时候需要做必要的维护。如果插入时所在的数据页已满,根据B+树的算法,这时候需要申请一个新的数据页,然后挪动部分数据过去,这个过程称为页分裂,会对性能造成较大影响。同时,页分裂还影响数据页的利用率,原本放在一个页的数据,分到两个页中,整体空间利用率降低大约50%。

页分裂的逆过程为页合并。当相邻两个页由于删除了数据,利用率很低之后,会将数据页做合并。

基于索引维护,讨论哪些场景应该使用自增主键,哪些情况不应该用。

当我们设置了自增主键,插入时可以不指定主键值,且插入符合递增插入,每次插入都是一次追加操作,不会挪动其他记录,也不会触发叶子结点的分裂。而以有业务逻辑的字段做主键,往往保证不了有序插入,这样就可能有页分裂。

除了考虑性能,从存储空间的角度来看,自增主键的字节数也往往较小,那么普通索引的叶子节点就会越小,占用的空间也会越小。

因此,从性能和存储空间角度,自增主键往往是更合理的选择。而有些业务场景,比如要求只有一个唯一索引,那么该索引列自然作为主键了。

参考资料:极客时间专栏《MySQL实战45讲》https://time.geekbang.org/column/intro/100020801?tab=catalog

相关推荐
韩立学长5 小时前
【开题答辩实录分享】以《自助游网站的设计与实现》为例进行选题答辩实录分享
java·mysql·spring
q_19132846957 小时前
基于Springboot+MySQL+RuoYi的会议室预约管理系统
java·vue.js·spring boot·后端·mysql·若依·计算机毕业设计
学海_无涯_苦作舟7 小时前
MySQL面试题
数据库·mysql·面试
君子剑mango8 小时前
MySQL8.0 窗口函数
数据库·mysql
vortex59 小时前
ORM是什么?如何理解ORM?ORM的优缺点?
java·数据库·sql·mysql·oracle·orm
九章-10 小时前
国企国产化替代标杆实践:金仓数据库赋能贵州磷化EMS系统自主可控升级
数据库·mysql·安全
麦麦鸡腿堡13 小时前
Java_MySQL介绍
java·开发语言·mysql
程序员阿鹏13 小时前
MySQL中给字段添加唯一约束的方式有哪些?
android·数据库·mysql
古月฿13 小时前
大学生素质测评系统设计与实现
java·vue.js·redis·mysql·spring·毕业设计
無量13 小时前
MySQL事务与锁机制深度剖析
后端·mysql