JAVA索引机制探寻

本文深入探讨了数据库索引的原理,从二叉树的不足引出B-TREE和B+树的概念,详细解释了B+树的优势,包括减少磁盘I/O次数和适合范围查询。还对比了MyISAM和InnoDB存储引擎的索引实现,以及介绍了创建和优化索引的策略,如最左前缀匹配原则、选择区分度高的列等。

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

索引:
一、什么是索引
MySQL官方对于索引的定义为:索引是帮助MySQL高效获取数据的数据结构。
数据库查询是数据库最主要的功能之一,我们都希望查询数据的速度尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化。最基本的查询算法当然是顺序查找,当然这种时间复杂度为O(N)的算法在数据量很大时显然是糟糕的,于是有了二分查找O(log N)、二叉树查找等。但是二分查找要求被检索数据有序,而二叉树查找只能应用于二叉查找树,但是数据本身的组织结构不可能完全满足各种数据结构。所以,在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
插曲:大O表示法。检查长度为n的列表,二分查找最坏的情况需要执行log N次操作,使用大O表示法来表示算法的运行时间,也就是O(log N)。括号里面指算法需要执行的操作次数。
二、优势
  类似大学图书馆建书目索引,提高数据检索效率,降低数据库的IO成本。
通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗。
三、劣势
  实际上索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占空间的。
  虽然索引大大提高了查询速度,同时确会降低更新表的速度,如对表进行INSERT、UPDATE、DELETE。
因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段。
四、数据结构
1、二叉树
这里写图片描述
从算法逻辑上,二叉树的查找速度和比较次数都是很小的,但是数据库索引必须考虑一个问题:磁盘IO。
索引往往以索引文件的形式存储在磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数。
当数据量很大的时候,索引文件也很大,无法一次性加载整个索引到内存,只能逐一加载每一个磁盘页(磁盘的储存单位)。

磁盘预读和局部性原理
这里写图片描述
从磁盘读取数据时,系统会将数据逻辑地址传给磁盘,磁盘的控制电路按照寻址逻辑将逻辑地址翻译成物理地址。
由于磁盘存取速度很低,为了提高效率,磁盘一般都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。
局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。
预读的长度一般为页(page)的整倍数。页是计算机管理存储器的逻辑块。

这里写图片描述
如上图二叉树这种结构,h明显要深的多。由于逻辑上很近的节点(父子)物理上可能很远,无法利用局部性;

很明显,二叉树的磁盘IO次数跟二叉树的深度有关,由于每个节点存储的元素数量有限,所以二叉树的深度h比较大,IO读写过于频繁,所以有了所谓的B树(多路平衡查找树)。

而B-TREE利用了磁盘预读,将一个节点的大小设为等于一个磁盘页,这样每个节点只需要一次I/O就可以完全载入。

2、B-树
一个 m 阶的B树满足以下条件:
a、每个结点至多拥有m棵子树;
b、根结点至少拥有两颗子树(存在子树的情况下);
d、除了根结点以外,其余每个分支结点至少拥有 m/2 棵子树;
d、所有的叶结点都在同一层上;
e、有 k 棵子树的分支结点则存在 k-1 个关键码,关键码按照递增次序进行排列;
f、关键字数量需要满足ceil(m/2)-1 <= n <= m-1;
这里写图片描述
第一次磁盘IO:
这里写图片描述
在内存中定位(和9比较):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值