哈希联接与合并联接
Vertica 优化器使用以下算法之一实施联接:
-
当联接表的投影已在联接列中排序时,使用合并联接。与哈希联接相比,合并联接较快并且使用较少的内存。
-
当联接表的投影尚未在联接列上排序时,使用哈希联接。在这种情况下,优化器会在内表的联接列上构建一个内存中的哈希表。优化器然后扫描外部表以查找与哈希表的匹配,并相应地联接两个表中的数据。如果整个哈希表可以拟合到内存中,则执行哈希联接的成本将非常低。如果哈希表必须写入磁盘,成本会显着增加。
在给定可用的投影的情况下,优化器会自动选择最合适的算法来执行查询。
促进合并联接
为了促进合并联接,请为联接表创建在联接谓词列上排序的投影。联接谓词列应该是 ORDER BY
子句中的第一列。
例如,表 first
和 second
定义如下,分别带有投影 first_p1
和 second_p1
。投影在 data_first
和 data_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.id
和 second.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_p
2 和 second_p2
(它们分别在联接列 first_p2.id
和 second_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;