Netezza - 从 SQL 的角度来看,啥是托管?
Posted
技术标签:
【中文标题】Netezza - 从 SQL 的角度来看,啥是托管?【英文标题】:Netezza - What is colocation in the perspective of SQL?Netezza - 从 SQL 的角度来看,什么是托管? 【发布时间】:2015-04-10 22:33:51 【问题描述】:我知道托管对于 Netezza 中的分布式连接很重要。在高层次上,它有以下定义:
All data for joins are located in the same SPU
我过去也与一些 Netezza 员工交谈过,他们提到如果所有表都分布在相同的列上并进行连接,则连接被认为是同地的。
但是,我还是觉得这个定义有点欠缺……根据我对 1-phase 和 2-phase GROUP BY 的理解,我怀疑 colocation 确实是按照以下定义运行的:
A join is considered colocated if the set of columns used in the join condition is a superset of the distribution keys of all participating tables.
这是一个正确的定义吗?我尝试在 NZ 寻找一个准确的托管定义,但我得到的只是一堆假设你已经知道定义的文章。
我们将不胜感激。谢谢!
编辑:根据 ScottMcG 的建议,我将 colocated join 的定义重新表述为:
1. It must be a HASH or MERGE SORT JOIN
2. Set of columns in join conditions must be superset of all distribution keys of all participating tables
3. ?
? #3 的标记是我需要解决的模棱两可的问题。根据 ScottMcG 的说法,每个表的分布键也必须相互连接。
假设表 A、B、C 分布在文本列 A.C1、A.C2、B.C3、B.C4、C.C5 和 C.C6 上,我们有以下联接。
SELECT * FROM A
INNER JOIN B "Join1"
ON A.C1=B.C3
INNER JOIN C "Join2"
ON A.C2=B.C4
AND A.C2=C.C6
AND [X]
现在,让我们提供一些 [X] 的可能定义。那么,Join2 将与 [X] 的哪些定义并置?
(1) [X] = A.C2 = 5
(2) [X] = A.C2 = B.C1 OR A.C2 = C.C5
(3) [X] = A.C1 IS NULL
(4) [X] = A.NonKeyColumn1 = B.NonKeyColumn2
【问题讨论】:
【参考方案1】:对于 Netezza,当连接中涉及的表不需要从它们永久驻留的数据片重新分配或广播以执行连接时,连接被认为是共置的。
只有在以下情况下才会发生这种情况:
连接所需的一组列是每个表的分布键中列的超集 参与连接的每个表都具有与其分布键相同的列集。 连接是等连接。这些条件与您在定义中建议的条件非常接近,并且是允许但不足以确保同地连接的必要条件。如果一个表足够小,优化器可能会决定预先广播其中一个表,即使它们分布在相同的列上,那么从技术上讲,这不是同位连接。
我应该补充的一个警告是,对于被视为与另一列“相同”的列,列值应该散列为相同的值。一般来说,这意味着列数据类型是相同的。一个例外是整数系列数据类型(byteint、smallint、int、bigint)只要在支持的范围内,就会散列到相同的值。
关于连接类型的效果,等连接将是这种形式。请注意,这可能是哈希连接或归并排序连接(如果数据类型可能是浮点数)。无论哪种情况,我们都不需要重新分配数据。在这些示例中,两个表都分布在 COL1 上。
SELECT ...
FROM TableA A
JOIN TableB B
ON A.COL1 = B.COL1
如果连接是基于表达式的连接,如下所示,那么您最终会重新分配或广播数据。对于“小于”连接,您必须能够确定 8 小于 9,但由于它们都将被散列到不同的数据切片,因此只有在将一个重定位到另一个时才能比较它们。
SELECT ...
FROM TableA A
JOIN TableB B
ON A.COL1 < B.COL1
SELECT ...
FROM TableA A
JOIN TableB B
ON A.COL1 - B.COL1 = 0
【讨论】:
我明白了。所以我提出的定义是require #1。在 #2 上,如果表 A 分布在 A.CustomerName 上,表 B 分布在 CardholderName 上,并且我们在 A.CustomerName = B.CardholderName 上加入了Join?我认为那不会是共同本地化的。那么考虑“相同”列的一种方法是条件必须是 LHS 和 RHS 必须具有 PK-FK 关系,或者两者都是 FK 指向同一个 PK?至于要求#3,这是我第一次看到它被提及。我知道它是 HASH JOIN 所必需的。那么我可以假设它必须是 HASH 的 colocated JOIN 的前提条件吗? 我认为,就在您发表评论时,我编辑了我的回复以澄清这一点。对于#2,重要的是列中的内容散列到相同的值。因此,对于“表 A 分布在 A.CustomerName 上,表 B 分布在 CardholderName 上,并且我们在 A.CustomerName = B.CardholderName 上有 Join”,只要 CustomerName 和 CardholderName 都是 varchar,那么你可以有一个并置连接,因为两者中的“SMITH”都会散列到相同的值。对于#3,让我在答案中添加更多内容以澄清。 有趣。因此,让我尝试对托管要求进行简单的形式化:(1)JOIN 必须是 HASH/MERGE SORT JOIN 和(2)连接所需的列集是每个表的分布键。至于 JOIN 类型,是否有一个页面可以对其要求和性质给出良好的正式定义?我唯一能找到的是 HASH JOIN 需要等号和相同的类型,EXIST JOIN 是 HASH JOIN 的一种特殊类型,而 NESTED LOOP JOIN 是 baddddd。如有必要,我可以就此提出新问题 我认为为了正式,您仍然需要指定 TableA 的分布键中使用的列必须连接到 TableB 的分布键中使用的列。例如:Col1 上的 TableA dist,Col2 上的 TableB dist,选择 TableA A join TableB B on A.col1=B.col1 和 A.col2=B.Col2 将满足您提出的#2,但需要重新分配。关于连接类型(SQL 隐含的类型(equi-、expression-)和支持的代码实现的类型(hash、NL、exists、MS 等))可能值得单独提出一个问题。 /跨度> 嗯,这是一条新信息。那么这是否意味着如果 TableA 的所有分布键都连接到 TableB 的任何分布键就可以实现托管?加入常量怎么样?让我更新我的帖子以获取示例以上是关于Netezza - 从 SQL 的角度来看,啥是托管?的主要内容,如果未能解决你的问题,请参考以下文章