【问题标题】:How much do B-trees reduce disk accesses?B 树减少了多少磁盘访问?
【发布时间】:2016-04-01 00:03:42
【问题描述】:

我刚刚阅读了 B-trees 数据结构,我有一些问题。我有一个疑问,任何博客都没有解释过(也许它太明显了,我错过了)。

B 树应该通过降低树的高度来减少磁盘访问。那么,如果减少磁盘访问次数是主要关注点,那么它有多大的不同呢?假设我只使用二叉树,那么我的节点比 n 元 B 树的节点需要更少的空间。所以我可以在一个页面中容纳更多节点,就像我可以使用胖 B 树节点一样。它如何影响磁盘访问?我们只是在谈论最坏的情况吗?

【问题讨论】:

  • @CalebKleveter 代码格式用于代码,而不是突出随机单词。

标签: data-structures b-tree


【解决方案1】:

您必须了解 B 树通常用于您具有分页数据访问权限的系统中。这是最常见的数据库系统。页面本质上是一块内存,您必须一次读取(和写入)它。如果不阅读整个页面,您将无法阅读页面的各个部分。

重要的是:将页面从磁盘读取到内存是昂贵的;比对已经在内存中的页面做任何事情要贵得多。因此,您希望尽量减少必须阅读的页数。

与二叉树相比,B 树在此方面具有多项优势——考虑到它们是专门为此目的而设计的,这不足为奇。

其中一个好处是降低了高度。如果您采用普通的二叉树,您可以在其中快速搜索。但是在这样做的时候,你会走进树的深处。一棵有 100 万个元素的树的深度已经是 20。所以,假设它是平衡的,你需要走下 20 个节点。与 B-tree 相比,高度要低很多。孩子的数量为 10(顺便说一句,非常低),我们已经将高度降低到大约 6。所以我们需要进行更少的比较,并且可能加载更少的页面。通常,以某种方式选择 B 树的顺序(即每个节点具有的子节点的数量),因此 单个节点 会填满整个页面。现在这听起来可能很愚蠢,因为您需要在该节点的键中进行搜索,但它大大降低了深度,因此您必须阅读的页面数量。

另一个好处是 B 树是平衡的。这确保了所有节点在任何时候都被大致相等数量的子节点填充。通常,这大约是其容量的 75%。由于节点填充了一个完整的页面,这意味着每个包含节点的页面都被填充到它的容量。这非常好,因为它优化了节点使用的空间并避免了不包含信息的页面中的漏洞(这对于二叉树来说是一个大问题,因为它们在设计上没有平衡)。另一个非常重要的影响是,这也确保了查找元素的操作数量(以及运行时间)是一致的。因此,对于所有情况,您的性能都非常可预测。对于数据库而言,这通常比拥有更好的最佳或平均情况更为重要,因为后者的性能可能会有所不同。

还有其他好处,例如不仅所有叶子都在同一级别,而且物理上彼此靠近,因为这可以缩短迭代元素时的查找时间。

基本上,B 树针对分页数据访问进行了优化,这使得它们非常特殊并针对这些目的进行了微调,从而使它们优于经典的二叉树(在许多其他应用程序中更简单、更高效)。

【讨论】:

  • 所以我了解到 B-tree 算法的设计确保了任何特定搜索将被遍历的节点总是彼此靠近,这是减少磁盘访问的主要原因。如果我错了,请纠正我。
  • 我认为您应该更新此部分:“具有 100 万个元素的树的深度已经为 20。因此,假设它是平衡的,您需要向下走 20 个节点。与 B 相比-tree,高度要低得多。孩子的数量为 10(顺便说一句,这非常低。)我们已经将高度降低到大约 6。“最后一句话与之前的关系令人困惑。跨度>
【解决方案2】:

B代表平衡,表示在B树中,每个节点的左右两侧大致保持相同的大小(子节点数)。

考虑这个例子: 将数字添加到二叉树如下:如果新数字大于当前节点,则将其添加到右侧,否则以相同的方式添加到左侧(子)树。

A) 想想如果将 1 到 100 的数字按升序相加会发生什么。

B) 现在想象一下,如果像这样添加它们 50, 25, 75, 12, 37, 62, 87, ... 会发生什么(即从区间的中间开始,然后递归地添加新间隔)

B-trees 添加新节点的方式是,即使您按照 A) 中的顺序添加它们,生成的树也类似于从 B) 生成的树

对于磁盘访问,想象一下必须从 A) 和 B) 查找树中的节点 100 并比较您必须处理多少个节点(磁盘访问)才能到达它。

编辑 正如 cmets 中所指出的,上述 B 树的表示并不完全正确。

B-tree 更像是排序(节点)列表的树,也就是说,每个节点都包含一个排序的键列表(它是可变的但长度有限),每个键都引用一个子节点或叶(数据节点)。这使得树比平衡二叉树(这基本上是我上面描述的)更平坦。每个节点都可以被视为必须完整读取的数据块或数据页。由于树相对平坦,查找特定数据点必须读取的页面数量很少。在 B-tree 中查找的复杂性与平衡二叉树的复杂性相当(或者就此而言,在排序列表上进行简单的二叉搜索)。区别在于必须在一个步骤中处理的键/数据的数量。二叉树需要对每个级别的单个数据点进行一次读取操作,排序列表需要一次读取所有数据,而 B 树位于中间,需要每个级别的数据块。从一些操作的角度来看是无关紧要的,从内存访问的角度来看它是非常重要的。从磁盘读取数据时,块的大小不如所需的单独读取操作的数量重要(只要它受到限制)。

【讨论】:

  • 感谢您的回复。我只是从磁盘访问的角度询问。在二叉树的情况下,我们可以在单个磁盘页面中容纳更多节点。我猜访问节点和访问磁盘不是一回事。
  • @KrrishRaj 你可以在一个页面中打包很多二叉树节点,但是访问模式只会在前几个级别有效,很快你需要的节点之间的距离会增加,直到您需要的每个节点都将位于一个页面上,该页面上没有您也需要的其他节点。渐近地,您将阅读与树的高度一样多的页面,减去一个常数。在 B 树中,它被一个常数
  • 附注:B-tree 中的“B”不一定代表平衡。这是一种可能的信念,但还有许多其他可能性,并且“B”没有确定的含义。 (当然这不会改变树仍然平衡的事实;))
  • 现在我想我明白了。在这两种情况下,整个树所需的页面数量都相同,但 B-tree 确保将在任何特定搜索中遍历的节点尽可能靠近,与二叉树相比,这减少了磁盘访问次数,因为在二叉树我们无法控制如何将节点写入磁盘。从长远来看,节点可能会随机分散在不同的页面上,并且对于每个下一个节点,我们可能必须加载不同的页面。如果我错了,请纠正我。 @PeterE
【解决方案3】:

目标是尽量减少磁盘寻道。读取或写入多少字节是次要的,因为顺序速度比磁盘上的随机访问快 100 倍。

这就是树高很重要的原因。

此外,树页面应该映射到物理设备块。如果每个节点只有两个值,则很难利用物理磁盘块拥有的所有空间。

【讨论】:

    猜你喜欢
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-14
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多