更新时间:2025-03-13 GMT+08:00

Hash Join

算子说明

哈希连接(Hash Join)是一种高效的连接方法,它依赖于哈希技术。在进行哈希连接时,GaussDB会先选取两个表中的一个(通常是小表),接下来根据连接条件,建立一个哈希表。哈希表的键是小表的连接字段,值是小表的其他字段。然后,对于大表中的每一行,计算连接字段的哈希值,并在哈希表中查找是否有匹配的行。

Hash Join的时间复杂度为O(n+m), 其中n和m分别代表两个表的行数。然而,如果内部表过大,以至于哈希表无法完全放入内存,则可能需要额外的磁盘I/O操作,这会导致性能降低。

典型场景

  • 当两个表的行数差距很大,并且进行连接操作。
  • 当两个表的连接字段是等值连接(比如使用=运算符)。

示例

示例:两个表的行数差距很大,并且进行连接操作。

--数据准备。 
gaussdb=# DROP TABLE IF EXISTS t1;
gaussdb=# DROP TABLE IF EXISTS t2;
gaussdb=# CREATE TABLE t1(c1 number,c2 number,c3 number); 
CREATE TABLE 
gaussdb=# CREATE TABLE t2(c1 number,c2 number,c3 number); 
CREATE TABLE 
gaussdb=# INSERT INTO t1 VALUES(generate_series(1,100000), 2 ,3); 
INSERT 0 100000 
gaussdb=# INSERT INTO t2 VALUES(generate_series(1,100), 2, 3); 
INSERT 0 100

--收集统计信息。
gaussdb=# ANALYZE t1;
gaussdb=# ANALYZE t2;

--执行结果。 
gaussdb=# EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.c1 = t2.c2; 
                                      QUERY PLAN
--------------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=12.56..986.88 rows=100 width=31)
   Node/s: All datanodes
   ->  Hash Join  (cost=9.44..982.19 rows=100 width=31)
         Hash Cond: (t1.c1 = t2.c2)
         ->  Seq Scan on t1  (cost=0.00..816.00 rows=100000 width=16)
         ->  Hash  (cost=8.19..8.19 rows=100 width=15)
               ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..8.19 rows=100 width=15)
                     Spawn on: All datanodes
                     ->  Seq Scan on t2  (cost=0.00..2.50 rows=100 width=15)
(9 rows)

--删除表。
gaussdb=# DROP TABLE t1,t2;

上述示例中,Hash Join算子输出信息如下所示。

信息名称

含义

Hash Join

算子的名称。

Hash Cond

算子Hash join的连接谓词,示例中条件为t1.c1等于t2.c2,在查询执行时,满足这些条件的行会被包含在最终的结果集中。

Hash

内表创建hash table的算子。