B树
https://blog.csdn.net/ligupeng7929/article/details/79529072
https://blog.csdn.net/qq_38038480/article/details/81738079
此篇原文:https://www.jianshu.com/p/528d30a5de76
数据库为什么使用B+树
1. 与二叉树相比
二叉树相比于顺序查找的确减少了查找次数,但是在最坏情况下,二叉树有可能退化为顺序查找。而且就二叉树本身来说,当数据库的数据量特别大时,其层数也将特别大。二叉树的高度一般是log_2^n,B树的高度是log_t^((n+1)/2) + 1,其高度约比B树大lgt倍。n是节点总数,t是树的最小度数。
假如每个盘块可以正好存放一个B树的结点(正好存放2个文件名)。那么一个BTNODE结点就代表一个盘块,而子树指针就是存放另外一个盘块的地址。
下面,咱们来模拟下B树索引查找文件29的过程:
根据根结点指针找到文件目录的根磁盘块1,将其中的信息导入内存。【磁盘IO操作 1次】
此时内存中有两个文件名17、35和三个存储其他磁盘页面地址的数据。根据算法我们发现:17<29<35,因此我们找到指针p2。
根据p2指针,我们定位到磁盘块3,并将其中的信息导入内存。【磁盘IO操作 2次】
此时内存中有两个文件名26,30和三个存储其他磁盘页面地址的数据。根据算法我们发现:26<29<30,因此我们找到指针p2。
根据p2指针,我们定位到磁盘块8,并将其中的信息导入内存。【磁盘IO操作 3次】
此时内存中有两个文件名28,29。根据算法我们查找到文件名29,并定位了该文件内存的磁盘地址。
2. 与B树相比
B树在提高IO性能的同时,并没与解决元素遍历时效率低下的问题,正是为了解决这个问题,B+数应运而生。B+数只需遍历叶子节点即可实现整棵树的遍历,而B树必须使用中序遍历按序扫库,B+树支持范围查询非常方便。这才是数据库选用B+树的主要原因。
另外,最后说一下,并不是说B+树就比B树好,有很多基于频率的搜索是选用B树,越频繁query的结点越往根上走,前提是需要对query做统计,而且要对key做一些变化。
无论是B树还是B+树由于前边几层反复query,因此早已被加载入内存,不会出现读磁盘IO。一般启动的时候,就会主动换入内存。在内存中B+树并没有优势,只有在磁盘中B+树的威力才能显现。
---------------------
2-3树,B树,B+树
多路查找树——相比于常用的二叉树,多路查找树每个节点可以存储多个元素和多个孩子指针。主要用于做索引,来降低程序对外存磁盘设备上的数据的访问次数。
- 【2-3树】
树中每个结点要么是2结点(即1个元素和2孩子指针或2NULL),要么是3结点(即2个元素和3个孩子指针或3NULL)。
- 【2-3-4树】
2-3树的扩展,增加了4结点的使用。树中每个结点要么是2结点(即1个元素和2孩子指针或2NULL),要么是3结点(即2个元素和3个孩子指针或3NULL),要么是4结点(即3个元素和4个孩子指针或4NULL)。 - 都要保证所有的叶子节点都在同一层次上,即保证平衡。因此每次插入和删除结点后,都可能要对叶子节点进行调整。
B树
B树结构做索引怎么就能降低程序对外存磁盘设备上的数据的访问次数呢?
B+树——对B树的改进,使得更适用于文件系统和数据库。
【B树示例】
【B+树示例】
- 可以看到,B+树的每个分支结点中只保存了索引值,而没有保存实际的数据值。这就使得每个结点(内存页面)可以存放更多个索引元素,进一步降低了树的高度,提高了查询的效率。
- 对于B树在遍历所有元素时有重复的缺陷,B+树只要从叶子节点从左往右遍历一遍就可以,不会发生重复。
B+树作为数据库索引的实例,其中0x56等为数据实际地址
为第一列数据做索引
为第二列数据做索引
数据库索引优化策略
-
高效使用索引的首要条件是知道什么样的查询会使用到索引,即查询语句要满足B+Tree中的“最左前缀原理”时,才会使用到已经创建的索引。
-
既然索引可以加快查询速度,那么是不是只要是查询语句需要,就建上索引?答案是否定的。因为索引虽然加快了查询速度,但索引也是有代价的:索引文件本身要消耗存储空间,同时索引会加重插入、删除和修改记录时的负担,另外,MySQL在运行时也要消耗资源维护索引,因此索引并不是越多越好。一般两种情况下不建议建索引。
第一种情况是表记录比较少。
第二种不建议建索引的情况是索引的选择性较低。所谓索引的选择性(Selectivity),是指不重复的索引值与表记录数的比值。越接近于1说明索引值唯一性越好,这对于B+树的维护和查询效率都很好。 -
有一种与索引选择性有关的索引优化策略叫做
前缀索引
,就是用列的前缀代替整个列作为索引key,当前缀长度合适时,可以做到既使得前缀索引的选择性接近全列索引,同时因为索引key变短
而减少了索引文件的大小和维护开销。