【问题标题】:Whats faster in Oracle? Small table with tree structure vs. Huge flat tableOracle 中什么速度更快?树形结构的小桌子与巨大的平桌
【发布时间】:2011-04-23 01:08:16
【问题描述】:

我正在设计一个将使用 Oracle 的应用程序,并且我们有这个部门层次结构,我们需要将其映射到我们的数据库中。一些看起来像这样的东西(我很确定你们都知道我在说什么,但我会附上 ERD 的一部分以防万一):

所以它将存储如下所示的数据:

[1 | 0]
[2 | 1]
[3 | 2]
[4 | 2]

换句话说:

Department 1
     |__Department 2
             |___Department 3
             |___Department 4

等等……

这将增加表上所需的记录数量,并且可以使用 CONNECT BY 命令访问数据,每个部门只有 1 条记录。我们通常采用这种树结构作为解决方案,但在这个新应用程序中,性能至关重要,所以我想知道如果我有一个看起来像这样的扁平表会怎样。

[1 | 0]
[2 | 1]
[3 | 1]
[3 | 2]
[4 | 1]
[4 | 2]

这使您可以建立非常明显的关系,而无需知道给定孩子的父部门即可知道他们的上层部门是谁。但这会增加所需的数据量,因为您需要一个部门所在的每个级别的记录,这意味着如果一个部门有 15 个级别低于最高级别,我们将需要 15 条记录。 该部门非常大,因此最终可能会变成一张巨大的表(大约 200 万条记录)。

好的,简单介绍完之后就是这个问题了;有没有人真正尝试过这个可以告诉我这两个选项之间的数据库更快/更便宜的是什么?巨大的平表或小树之一?

【问题讨论】:

  • 这提醒我检查 CONNECT BY 语法(自 v2 起受支持)和 Oracle 从 11gR2 起才开始支持的递归 WITH(分层/递归查询的 ANSI 标准)之间是否存在性能差异。 .

标签: sql oracle database-design oracle10g query-optimization


【解决方案1】:

我肯定会选择第一个选项(分层方法)。我认为正确地对数据进行建模比仅仅使用糟糕的数据模型来获得性能更好。由于您在此处对层次结构进行建模,因此以这种方式将其存储在数据库中是有意义的。

如果您想要两全其美,我的建议是考虑使用 materialized view 来“展平”分层数据,然后您仍然可以正确存储数据,但您可以获得性能提升(如果有的话) 通过使用物化视图。

几乎总有一种方法可以遵循良好的数据模型,并且仍然可以找到获得良好性能的方法。但是一个糟糕的数据模型会让你在未来几年内付出代价,而且以后要纠正它会非常痛苦

但是,即使使用扁平化方法,您也必须考虑到您正在显着增加记录数量,尤其是当您到达树中的叶节点时,所以如果有一个扁平的层次结构表,我会感到惊讶(您的第二种方法)将提高性能,因为要处理的记录更多。

【讨论】:

  • 这正是问题的重点..,如果您必须在大表中进行简单直接的查询或在小表中进行连接之间进行选择,那么性能是您唯一关心的问题。 ..你会选择什么,为什么?我的意思是,我完全同意你关于良好模型与性能的观点。
  • @Chepech - 我不想在这里回避这个问题,但性能永远不会是我唯一关心的问题。我首先会努力使数据模型正确。我以前使用过设计糟糕的数据库(没有参照完整性,到处都是数据重复等),这是一场噩梦。话虽如此,我仍然认为 connect by 在这种情况下会表现得更好,因为与仅正确存储层次结构相比,记录数呈指数增长(存储平面层次结构时在叶级别)。
  • 我不是在暗示。我也有“机会”使用 DB 模型,这些模型看起来像是从某种农场动物的后端出来的,所以我知道你的意思。
【解决方案2】:

快速访问分层数据的替代方法是嵌套集数据模型:

Nested Set on Wiki

它允许您单次访问所有子节点, 无论深度如何,但可能需要离线维护, 取决于你的实施。

【讨论】:

    【解决方案3】:

    如果您需要读取性能,请尝试路径枚举。

    [1 | 0]
    [2 | 1]
    [3 | 2]
    [4 | 2]
    

    变成

    [1 | '0']
    [2 | '0.1']
    [3 | '0.1.2']
    [4 | '0.1.2']
    

    所以你可以选择 2 的所有孩子

    SELECT * FROM dept WHERE path LIKE '0.1.2%'
    

    当然,这是规范化和性能之间的折衷。

    【讨论】:

    • 这个主意不错,但问题是,如果我想修改部门结构怎么办? ......所有的地狱都松散了。这也需要字符串比较和某种解析,最终它可能会使事情变慢。
    • 是的,读性能很好,写性能很差,所以这是只写一次读多类型表的解决方案。对于关系数据库中的分层数据,没有标准的最佳解决方案,一切都是妥协。
    【解决方案4】:

    对于像 Departments 这样的东西,表中不可能有足够的记录来解决性能问题。甚至不用担心。

    即使有一些其他类型的分层数据,其中可能有太多的记录会影响性能,也总是有其他技术/方法来解决这些性能问题(当它们弹出时),以及实施这些问题的成本其他解决方案几乎总是比您尝试针对平面模式编写系统代码所增加的开发和维护工作量要少。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-11
      • 2019-11-15
      • 2010-10-23
      • 2011-02-12
      • 2014-12-30
      • 2011-11-08
      • 2011-05-04
      • 2019-04-02
      相关资源
      最近更新 更多