哈希联接与合并联接

Vertica 优化器使用以下算法之一实施联接:

  • 当联接表的投影已在联接列中排序时,使用合并联接。与哈希联接相比,合并联接较快并且使用较少的内存。

  • 当联接表的投影尚未在联接列上排序时,使用哈希联接。在这种情况下,优化器会在内表的联接列上构建一个内存中的哈希表。优化器然后扫描外部表以查找与哈希表的匹配,并相应地联接两个表中的数据。如果整个哈希表可以拟合到内存中,则执行哈希联接的成本将非常低。如果哈希表必须写入磁盘,成本会显着增加。

在给定可用的投影的情况下,优化器会自动选择最合适的算法来执行查询。

促进合并联接

为了促进合并联接,请为联接表创建在联接谓词列上排序的投影。联接谓词列应该是 ORDER BY 子句中的第一列。

例如,表 firstsecond 定义如下,分别带有投影 first_p1second_p1。投影在 data_firstdata_second 上排序:

CREATE TABLE first ( id INT, data_first INT );
CREATE PROJECTION first_p1 AS SELECT * FROM first ORDER BY data_first;

CREATE TABLE second ( id INT, data_second INT );
CREATE PROJECTION second_p1 AS SELECT * FROM second ORDER BY data_second;

当您在未排序的列 first.idsecond.id 上联接这些表时,Vertica 使用哈希联接算法:

 EXPLAIN SELECT first.data_first, second.data_second FROM first JOIN second ON first.id = second.id;

 Access Path:
 +-JOIN HASH [Cost: 752, Rows: 300K] (PATH ID: 1) Inner (BROADCAST)

您可以创建投影 first_p2 和 second_p2(它们分别在联接列 first_p2.idsecond_p2.id 上排序),从而使用合并联接算法促进执行此查询:


CREATE PROJECTION first_p2 AS SELECT id, data_first FROM first ORDER BY id SEGMENTED BY hash(id, data_first) ALL NODES;
CREATE PROJECTION second_p2 AS SELECT id, data_second FROM second ORDER BY id SEGMENTED BY hash(id, data_second) ALL NODES;

如果查询联接了大量数据,则查询优化器使用合并算法:

EXPLAIN SELECT first.data_first, second.data_second FROM first JOIN second ON first.id = second.id;

 Access Path:
 +-JOIN MERGEJOIN(inputs presorted) [Cost: 731, Rows: 300K] (PATH ID: 1) Inner (BROADCAST)

您还可以使用子查询对联接谓词列进行预排序,从而促进合并联接。例如:

SELECT first.id, first.data_first, second.data_second FROM
  (SELECT * FROM first ORDER BY id ) first JOIN (SELECT * FROM second ORDER BY id) second ON first.id = second.id;