【问题标题】:Perform Joins in O(n) time?在 O(n) 时间内执行连接?
【发布时间】:2011-04-05 20:18:31
【问题描述】:

有没有办法在线性时间内加入 2 个表?我听说这可以通过使用另一个数据结构(哈希表)来完成,但我不确定如何做到这一点。我一直想知道 Join 会涉及一个叉积,因此它是 O(n^2)。

【问题讨论】:

标签: algorithm database-design data-structures database


【解决方案1】:

算法:

循环遍历表 A。散列所有项目,将它们添加到 Join 数组中。
遍历表B,检查每个项目是否在哈希表中(检查-O(1)),如果没有,则添加到Join表中。

【讨论】:

    【解决方案2】:

    如果在连接中使用的列上有可用的索引,则它是线性的,因为索引允许按顺序遍历两个表。 (当然,这不包括摊销指数成本。)

    散列连接将是某种线性的,尽管散列本身不是免费的,而且当涉及的键很长时,成本也会上升。

    【讨论】:

    • OK - 请注意,虽然索引原则上可以进行线性时间连接,但如果统计数据表明其中一个有效表要小得多,服务器可能会决定进行哈希连接比另一个。
    • 是的,为了提高效率,必须检查 2 个表的大小。
    【解决方案3】:

    这取决于连接的类型。交叉连接总是 O(n^2),因为它必须产生 O(n^2) 记录。如果使用正确的数据结构,则可以以更高的复杂度(O(n log(n)) 甚至可能摊销 O(n))完成等连接。

    【讨论】:

    • 我在寻找自然连接的时间复杂度
    • 连接类型无关紧要。取两个具有不相交列的表,为每条记录添加一个值为 0 的公共虚拟列。自然连接的复杂度仍然是二次的,因此是最坏情况的估计。
    【解决方案4】:

    您可以通过使用哈希表根据另一个表的 id 在一个表中查找记录,以接近 O(n) 的方式连接两个表。

    嗯,实际上运算会接近O(n+m),其中nm是两个表中的项目数。您将首先遍历一个表中的记录以根据该表中的键构建一个哈希表,然后您将遍历另一个表以在哈希表中查找每个记录的匹配项。

    在哈希表中查找项目不是 O(1) 操作,但它很接近。数据越多,哈希冲突就越多,因此某些查找需要进行不止一次比较。

    【讨论】:

      【解决方案5】:

      主要的数据库供应商很久以前就弃用了哈希索引。因此,在 O(max(n,m)) 时间内加入 2 个表实际上并不重要。使用标准 B 树索引,连接复杂度为 O(min(n,m)*log(max(n,m))。

      【讨论】:

        猜你喜欢
        • 2015-06-29
        • 2013-11-01
        • 1970-01-01
        • 2022-12-03
        • 2018-11-12
        • 2014-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多