相同分段
要在联接多个表时提升查询性能,请创建在联接键上进行相同分段的投影。使用相同分段的投影时,联接可以在每个节点本地进行,因此有助于在查询处理期间减少整个网络中的数据移动。
要确定投影是否在查询联接键中进行了相同分段,请创建具有 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;