相同分段

要在联接多个表时提升查询性能,请创建在联接键上进行相同分段的投影。使用相同分段的投影时,联接可以在每个节点本地进行,因此有助于在查询处理期间减少整个网络中的数据移动。

要确定投影是否在查询联接键中进行了相同分段,请创建具有 EXPLAIN 的查询计划。如果查询计划包括 RESEGMENTBROADCAST,则表示投影没有进行相同分段。

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} 中。

  • p1p2 的分段表达式必须在结构上等效。例如:

    • 如果 p1SEGMENTED BY hash(t1.x) 并且 p2SEGMENTED BY hash(t2.x),那么 p1p2 进行了相同分段。

    • 如果 p1SEGMENTED BY hash(t1.x) 并且 p2SEGMENTED BY hash(t2.x + 1),那么 p1p2 没有进行相同分段。

  • p1p2 必须有相同的分段计数。

  • 向节点分配的分段必须匹配。例如,如果 p1p2 使用了 OFFSET 子句,它们的偏移必须匹配。

  • 如果 Vertica 发现 t1t2 的投影没有进行相同分段,必要时数据会在查询运行时在整个网络中重新分布。

示例

以下语句创建了两个表,并指定要创建相同分段:

=> 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;

另请参阅