- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章MySQL中B树索引和B+树索引的区别详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
如果用树作为索引的数据结构,每查找一次数据就会从磁盘中读取树的一个节点,也就是一页,而二叉树的每个节点只存储一条数据,并不能填满一页的存储空间,那多余的存储空间岂不是要浪费了?为了解决二叉平衡搜索树的这个弊端,我们应该寻找一种单个节点可以存储更多数据的数据结构,也就是多路搜索树.
1、完全二叉树高度:O(log2N),其中2为对数,树每层的节点数; 。
2、完全M路搜索树的高度:O(logmN),其中M为对数,树每层的节点数; 。
3、M路搜索树主要用于解决数据量大无法全部加载到内存的数据存储。通过增加每层节点的个数和在每个节点存放更多的数据来在一层中存放更多的数据,从而降低树的高度,在数据查找时减少磁盘访问次数.
4、所以每层的节点数和每个节点包含的关键字越多,则树的高度越矮。但是在每个节点确定数据就越慢,但是B树关注的是磁盘性能瓶颈,所以在单个节点搜索数据的开销可以忽略.
B树是一种M路搜索树,B树主要用于解决M路搜索树的不平衡导致树的高度变高,跟二叉树退化为链表导致性能问题一样。B树通过对每层的节点进行控制、调整,如节点分离,节点合并,一层满时向上分裂父节点来增加新的层等操作来来保证该M路搜索树的平衡.
M为B树的阶数或者说是路数,在B树中,每个节点都是一个磁盘块(页)。每个非叶子节点存放了关键字和指向儿子树的指针,具体数量为:M阶的B树,每个非叶子节点存放了M-1个关键字和M个指向子树的指针。如图为5阶B树结构的示意图:
首先创建一张user表:
create table user( id int, name varchar, primary key(id)) ROW_FORMAT=COMPACT;
假如我们使用B树对表中的用户记录建立索引:
B树的每个节点占用一个磁盘块,磁盘块也就是页,从上图可以看出,B树相对于平衡二叉树,每个节点存储了更多的主键key和数据data,并且每个节点拥有了更多的子节点,子节点的个数一般称为阶,上述图中的B树为3阶B树,高度也会降低。假如我们要查找id=28的用户信息,那么查找流程如下:
1、根据根节点找到页1,读入内存。【磁盘I/O操作第1次】 。
2、比较键值28在区间(17,35),找到页1的指针p2; 。
3、根据p2指针找到页3,读入内存。【磁盘I/O操作第2次】 。
4、比较键值28在区间(26,35),找到页3的指针p2.
5、根据p2指针找到页8,读入内存。【磁盘I/O操作第3次】 。
6、在页8中的键值列表中找到键值28,键值对应的用户信息为(28,po); 。
B-Tree相对于AVLTree缩减了节点个数,使每次磁盘I/O取到内存的数据都发挥了作用,从而提高了查询效率.
B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,B+树的性质:
1、非叶子节点的子树指针与关键字个数相同; 。
2、为所有叶子节点增加一个链指针; 。
3、所有关键字都在叶子节点出现, 且链表中的关键字恰好是有序的; 。
4、非叶子节点相当于是叶子节点的索引,叶子节点相当于是存储(关键字)数据的数据层; 。
InnoDB存储引擎就是用B+Tree实现其索引结构.
从上一节中的B-Tree结构图中可以看到每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度.
B+Tree相对于B-Tree有几点不同:
1、非叶子节点只存储键值信息和指向子节点页号的指针; 。
2、所有叶子节点之间都有一个链指针; 。
3、数据记录都存放在叶子节点中; 。
根据上图我们来看下 B+ 树和 B 树有什么不同:
(1) B+ 树非叶子节点上是不存储数据的,仅存储键值,而 B 树节点中不仅存储键值,也会存储数据.
页的大小是固定的,InnoDB 中页的默认大小是 16KB。如果不存储数据,那么就会存储更多的键值,相应的树的阶数就会更大,树就会更矮更胖,如此一来我们查找数据进行磁盘的 IO 次数又会再次减少,数据查询的效率也会更快.
另外,如果我们的 B+ 树一个节点可以存储 1000 个键值,那么 3 层 B+ 树可以存储 1000×1000×1000=10 亿个数据。一般根节点是常驻内存的(第一次检索根节点不用读取磁盘),所以一般我们查找 10 亿数据,只需要 2 次磁盘 IO.
(2) B+ 树索引的所有数据均存储在叶子节点,而且数据是按照顺序排列的.
B+ 树中各个页之间是通过双向链表连接的,叶子节点中的数据是通过单向链表连接的,通过这种方式可以找到表中的所有数据。B+ 树使得范围查找,排序查找,分组查找以及去重查找变得异常简单。而 B 树因为数据分散在各个节点,要实现这一点是很不容易的.
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我的更多内容! 。
原文地址:https://hengheng.blog.csdn.net/article/details/123025973 。
最后此篇关于MySQL中B树索引和B+树索引的区别详解的文章就讲到这里了,如果你想了解更多关于MySQL中B树索引和B+树索引的区别详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这几天我一直在努力。我一直在自学 CSS,所以对菜鸟好一点。我正在创建一个推荐 slider 。推荐以 3 个 block 显示。我希望前 2 个下降,第 3 个上升。但是当 slider 激活时,无
我最近开始学习 Nodejs,现在我很困惑我的网络应用程序使用什么,html 还是 ejs (Express)。 Ejs 使用 Express 模块,而 .html 使用 HTML 模块。我的第一个问
假设我们有一个 PostgreSQL 表contacts,每条记录都有一堆带标签的电子邮件地址(标签和电子邮件对)——其中一个是“主要”。 存储方式如下: id 主键 电子邮件 文本 email_la
我成功为一种新的tesseract语言编写了traineddata文件,但是当我完成时,我继续收到以下错误: index >= 0 && index = 0 && 索引 < size_used_ :E
这个问题已经有答案了: How to deal with SettingWithCopyWarning in Pandas (21 个回答) 已关闭 4 年前。 假设我有一个像这样的数据框,第一列“密
如果我有一个位置或行/列同时用于 A 和 B 位置,请检查 B 是否与 A 成对角线? 1 2 3 4 5 6 7 8 9 例如,我如何检查 5 是否与 7 成对角线? 此外,如果我检查 4 是
MongoDB:索引 一、 创建索引 默认情况下,集合中的_id字段就是索引,我们可以通过getIndexes()方法来查看一个集合中的索引 > db.user.getIndexes() [ { "v
一、索引介绍 索引是一种用来快速查询数据的数据结构。 B+Tree就是一种常用的数据库索引数据结构,MongoDB采用B+Tree 做索引,索引创建在colletions上。 MongoDB不使用索引
我无法决定索引。 就像我有下面的查询需要太多时间来执行: select count(rn.NODE_ID) as Count, rnl.[ISO_COUNTRY_CODE] as Cou
我有这些表: CREATE TABLE `cstat` ( `id_cstat` bigint(20) NOT NULL, `lang_code` varchar(3) NOT NULL,
我正在尝试找到一种方法来提高包含 IP 范围的 mysql 表的性能(在高峰时段每秒最多有 500 个 SELECT 查询(!),所以我有点担心)。 我有一个这种结构的表: id smallint(
jquery index() 似乎无法识别元素之一,总是说“无法读取未定义的属性‘长度’”这是我的代码。mnumber 是导致问题的原因。我需要 number 和 mnumber 才能跟踪使用鼠标,并
我们有一个包含近 4000 万条记录的 MongoDB 集合。该集合的当前大小为 5GB。此集合中存储的数据包含以下字段: _id: "MongoDB id" userid: "user id" (i
文档说:如果你有多个字段的复合索引,你可以用它来查询字段的开始子集。所以如果你有一个索引一个,乙,丙你可以用它查询一种一个,乙a,b,c 我的问题是,如果我有一个像这样的复合索引一个,乙,丙我可以查询
我正在使用 $('#list option').each(function(){ //do stuff }); 循环列表中的选项。我想知道如何获取当前循环的索引? 因为我不想让 var i = 0;循
MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度。 打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL
SQLite 索引(Index) 索引(Index)是一种特殊的查找表,数据库搜索引擎用来加快数据检索。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书后边的索引是非常相似的。
我是 RavenDB 的新手。我正在尝试使用多 map 索引功能,但我不确定这是否是解决我的问题的最佳方法。所以我有三个文件:Unit、Car、People。 汽车文件看起来像这样: { Id: "
我有以下数据,我想根据范围在另一个表中建立索引 我想要实现的是,例如,如果三星的销售额为 2500,则折扣为 2%,低于 3000 且高于 1000 我知道它可以通过索引来完成,与多个数组匹配,然后指
我正在检查并删除 SQL 数据库中的重复和冗余索引。 所以如果我有两个相同的索引,我会删除。 例如,如果我删除了重叠的索引... 索引1:品牌、型号 指标二:品牌、型号、价格 我删除索引 1。 相同顺
我是一名优秀的程序员,十分优秀!