相同分段
要在联接多个表时提升查询性能,请创建在联接键上进行相同分段的投影。使用相同分段的投影时,联接可以在每个节点本地进行,因此有助于在查询处理期间减少整个网络中的数据移动。
要确定投影是否在查询联接键中进行了相同分段,请创建具有 EXPLAIN
的查询计划。如果查询计划包括 RESEGMENT
或 BROADCAST
,则表示投影没有进行相同分段。
Vertica 优化器会选择投影为查询中的每个表提供行。如果要联接的投影进行了分段,那么优化器则会根据查询联接表达式评估其分段。因此,它会确定行是否放置在每个节点上,以便于它联接行,而无需从其他节点获取数据。
相同分段的投影的联接条件
如果 p
的分段表达式的所有列引用是联接表达式中的列的子集,那么投影 p
会在联接列上进行分段。
如果表 t1
的分段投影 p1
和表 t2
的分段投影 p2
这两个分段投影要使 t1
联接到 t2
,则必须满足以下条件:
-
联接条件必须采用以下形式:
t1.j1 = t2.j1 AND t1.j2 = t2.j2 AND ... t1.jN = t2.jN
-
联接列必须共享相同的基本数据类型。例如:
-
如果
t1.j1
是 INTEGER,则t2.j1
可以是 INTEGER,但它不能是 FLOAT。 -
如果
t1.j1
是 CHAR(10),则t2.j1
可以是任何 CHAR 或 VARCHAR(例如,CHAR(10)、VARCHAR(10)、VARCHAR(20)),但是t2.j1
不能是 INTEGER。
-
-
如果
p1
按列 {t1.s1, t1.s2, ... t1.sN
} 上的表达式分段,则每个分段列t1.sX
必须位于联接列集 {t1.jX
} 中。 -
如果
p2
按列 {t2.s1, t2.s2, ... t2.sN
} 上的表达式分段,则每个分段列t2.sX
必须位于联接列集 {t2.jX
} 中。 -
p1
和p2
的分段表达式必须在结构上等效。例如:-
如果
p1
是SEGMENTED BY hash(t1.x)
并且p2
是SEGMENTED BY hash(t2.x)
,那么p1
和p2
进行了相同分段。 -
如果
p1
是SEGMENTED BY hash(t1.x)
并且p2
是SEGMENTED BY hash(t2.x + 1)
,那么p1
和p2
没有进行相同分段。
-
-
p1
和p2
必须有相同的分段计数。 -
向节点分配的分段必须匹配。例如,如果
p1
和p2
使用了OFFSET
子句,它们的偏移必须匹配。 -
如果 Vertica 发现
t1
和t2
的投影没有进行相同分段,必要时数据会在查询运行时在整个网络中重新分布。提示
如果您创建了自定义设计,请尝试在条件允许时为联接使用分段投影。
示例
以下语句创建了两个表,并指定要创建相同分段:
=> CREATE TABLE t1 (id INT, x1 INT, y1 INT) SEGMENTED BY HASH(id, x1) ALL NODES;
=> CREATE TABLE t2 (id INT, x1 INT, y1 INT) SEGMENTED BY HASH(id, x1) ALL NODES;
以此设计为例,以下查询中的联接条件可以利用相同分段:
=> SELECT * FROM t1 JOIN t2 ON t1.id = t2.id;
=> SELECT * FROM t1 JOIN t2 ON t1.id = t2.id AND t1.x1 = t2.x1;
相反,以下查询中的联接条件需要重新分段:
=> SELECT * FROM t1 JOIN t2 ON t1.x1 = t2.x1;
=> SELECT * FROM t1 JOIN t2 ON t1.id = t2.x1;