【发布时间】:2011-04-05 20:18:31
【问题描述】:
有没有办法在线性时间内加入 2 个表?我听说这可以通过使用另一个数据结构(哈希表)来完成,但我不确定如何做到这一点。我一直想知道 Join 会涉及一个叉积,因此它是 O(n^2)。
【问题讨论】:
-
@Andrey 和 @Pointy:非常感谢您提供的链接 :)
标签: algorithm database-design data-structures database
有没有办法在线性时间内加入 2 个表?我听说这可以通过使用另一个数据结构(哈希表)来完成,但我不确定如何做到这一点。我一直想知道 Join 会涉及一个叉积,因此它是 O(n^2)。
【问题讨论】:
标签: algorithm database-design data-structures database
算法:
循环遍历表 A。散列所有项目,将它们添加到 Join 数组中。
遍历表B,检查每个项目是否在哈希表中(检查-O(1)),如果没有,则添加到Join表中。
【讨论】:
如果在连接中使用的列上有可用的索引,则它是线性的,因为索引允许按顺序遍历两个表。 (当然,这不包括摊销指数成本。)
散列连接将是某种线性的,尽管散列本身不是免费的,而且当涉及的键很长时,成本也会上升。
【讨论】:
这取决于连接的类型。交叉连接总是 O(n^2),因为它必须产生 O(n^2) 记录。如果使用正确的数据结构,则可以以更高的复杂度(O(n log(n)) 甚至可能摊销 O(n))完成等连接。
【讨论】:
您可以通过使用哈希表根据另一个表的 id 在一个表中查找记录,以接近 O(n) 的方式连接两个表。
嗯,实际上运算会接近O(n+m),其中n和m是两个表中的项目数。您将首先遍历一个表中的记录以根据该表中的键构建一个哈希表,然后您将遍历另一个表以在哈希表中查找每个记录的匹配项。
在哈希表中查找项目不是 O(1) 操作,但它很接近。数据越多,哈希冲突就越多,因此某些查找需要进行不止一次比较。
【讨论】:
主要的数据库供应商很久以前就弃用了哈希索引。因此,在 O(max(n,m)) 时间内加入 2 个表实际上并不重要。使用标准 B 树索引,连接复杂度为 O(min(n,m)*log(max(n,m))。
【讨论】: