[MySQL]索引的种类和索引的选取感悟

本文深入探讨了数据库索引的多种数据结构,如哈希表、有序数组和B+树,详细分析了B+树在MySQL InnoDB引擎中的应用,包括主键索引和非主键索引的区别,以及索引选择和维护的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

数据库查询慢的时候,往往想到索引。

索引一般问起来,会考虑他的数据结构的选用,以及B+树的特点~

在mysql中,索引是在存储引擎中实现的。不同的引擎缩印的工作方式是不同的

1.索引常见的数据结构

常见的数据结构包括:哈希表,有序数组和搜索树。

在navicate中以:hash和btree来呈现~

1.1 索引如果选用hash

以K V形式存储,解决冲突方式类似于HashMap,用数组+链表的形式来实现。

hash作为索引,在等值的查询场景中非常优秀。

hash只适合于菲关系型数据库或者Memcached

仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询; (<=>就是mysql中的等于号,但是<=>是mysql特有的,在这里记录一下。)

查询效率很高

1.2 有序数组(在innodb中没有这种索引形式)

等值查询和范围查询都很优秀。

有序的话+二分查找就是很快的处理解决问题的方法~

但是这种有序数组,为什么用的很少?

是因为更新数据的时候很麻烦,中间插入一条数据就需要移动后面所有的数据。

需要很高的成本,所以有序数组索引只适用于静态存储引擎。

后面再也不会修改的东西。

1.3 b树

首先是二叉搜索树的特点:

二叉搜索树的特点是:每个节点的左儿子小于父节点,父节点又小于右儿子。

为了维持 O(log(N)) 的查询复杂度,你就需要保持这棵树是平衡二叉树;

多叉树就是每个节点有多个儿子,儿子之间的大小保证从左到右递增。二叉树是搜索效率最高的,但是实际上大多数的数据库存储却并不使用二叉树。其原因是,索引不止存在内存中,还要写到磁盘上。

在硬盘中查询访问,涉及到操作系统的原理。(寻址时间)

为了让一个查询尽量少地读磁盘,就必须让查询过程访问尽量少的数据块。(这也是使用B+树的原因)

MySQL实战45讲 林晓斌中提到:

使用“N 叉”树。这里,“N 叉”树中的“N”取决于数据块的大小。以 InnoDB 的一个整数字段索引为例,这个 N 差不多是 1200。这棵树高是 4 的时候,就可以存 1200 的 3 次方个值,这已经 17 亿了。考虑到树根的数据块总是在内存中的,一个 10 亿行的表上一个整数字段的索引,查找一个值最多只需要访问 3 次磁盘。其实,树的第二层也有很大概率在内存中,那么访问磁盘的平均次数就更少了。

每一个索引都对应了一个B+树。

1.3.1 主键索引和非主键索引?

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

主键索引的叶子节点存的是整行数据。在 InnoDB 里,主键索引也被称为聚簇索引(clustered index)。

非主键索引的叶子节点内容是主键的值。在 InnoDB 里,非主键索引也被称为二级索引(secondary index)。

1.3.2 使用主键索引好处?回表是什么?

主键查询只需要搜索ID这个树就可以了。但是如果是普通索引,我们必须先搜索这个索引的索引树,然后根据条件找到对应的主键,然后再用主键索引树搜索一次。这个过程叫做回表。

所以尽量使用主键查询。

1.3.3 B+树插入新值的调整过程?

涉及到重点关键字:

页分裂:如果想插入到的数据页已经满了,那么B+树会申请一个新的数据页,移动部分数据过去,这个过程叫做页分裂。

页分裂操作还影响数据页的利用率。原本放在一个页的数据,现在分到两个页中,整体空间利用率降低大约 50%。

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

1.4 索引的选取感悟

能用主键就用主键,需要建立非主键索引的时候,那么尽量保证主键是int或者数字形式。

因为int占了四个字节,而非主键索引树 叶子节点的数据内容是存放了主键。

所以如果主键站的字节很大,会导致非主键索引变大。

适合用业务字段直接做主键的场景:只有一个索引;该索引必须是唯一索引。(也就是不建立其他索引了,直接用业务字段查询条件)

2. 总结

每一张表实际上是N个B+数(因为主键就是一个B+树的存储结构,只不过数据节点是整个行的信息)

查询如果不走索引就是遍历整个索引二叉树。(遍历主键索引)

N叉树的N值在MySQL中是怎么调整?--后面去了解一下

没有主键的表,innodb会给默认创建一个Rowid做主键

索引是为了方便定位到数据页;

很重要!!innodb B+树主键索引的叶子节点存的是页page;一个页可以存多个行!!!

插入数据如果是在某个数据满了页的首尾,为了减少数据移动和页分裂,会先去前后两个页看看是否满了,如果没满会先将数据放到前后两个页上,不知道是不是有这种情况

删除主键的时候其实是重建整张表

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值