Runtime Filter
Hologres从V2.0版本开始支持Runtime Filter,在多表Join场景下自动优化Join过程的过滤行为,提升Join的查询性能。本文为您介绍在Hologres中Runtime Filter的使用。
背景信息
应用场景
Hologres从 V2.0版本开始支持Runtime Filter,通常应用在多表(2表及以上)Join,尤其是大表Join小表的场景中,无需手动设置,优化器和执行引擎会在查询时自动优化Join过程的过滤行为,使得扫描更少的数据量,从而降低IO开销,以此提升Join的查询性能。
原理介绍
在了解Runtime Filter原理之前,需先了解Join过程。两个表Join的SQL示例如下:
select * from test1 join test2 on test1.x = test2.x;
其对应的执行计划如下。

如上执行计划,两个表Join时,会通过test2
表构建Hash表,然后匹配test1
表的数据,最后返回结果。在这个过程中,Join时会涉及到两个名词:
build端:两表(或者子查询)做Hash Join时,其中一张表(子查询)的数据会构建成Hash表,这一部分称为build端,对应计划里的Hash节点。
probe端:Hash Join的另一边,主要是读取数据然后和build端的Hash表进行匹配,这一部分称为probe端。
通常来说,在执行计划正确的情况下,小表是build端,大表是probe端。
Runtime Filter的原理就是在Join过程中,根据build端的数据特征和分布以及最终Join的数据量和原始扫描数据量,自动对probe端的数据进行裁剪,从而减少对probe端的数据扫描和Shuffler,以此来提升Join性能。
因此Runtime Filter更适用于大小表Join,且表数据量相差较大的场景,性能将会比普通Join有更多的提升。
使用限制和触发条件
使用限制
仅Hologres V2.0及以上版本支持Runtime Filter。
仅支持Join条件中只有一个字段,如果有多个字段将不会触发Runtime Filter。
触发条件
Hologres本身支持高性能的Join,因此Runtime Filter会根据查询条件在底层自动触发,但是需要SQL满足下述所有条件才能触发:
probe端的数据量在100000行及以上。
扫描的数据量比例:
build端 / probe端 <= 0.1
(比例越小,越容易触发Runtime Filter)。Join出的数据量比例:
build端 / probe端 <= 0.1
(比例越小,越容易触发Runtime Filter)。
Runtime Filter示例
如下示例帮助您更好理解Runtime Filter。
begin;
create table test1(x int, y int);
call set_table_property('test1', 'distribution_key', 'x');
create table test2(x int, y int);
call set_table_property('test2', 'distribution_key', 'x');
end;
insert into test1 select t, t from generate_series(1, 100000) t;
insert into test2 select t, t from generate_series(1, 1000) t;
analyze test1;
analyze test2;
explain select * from test1 join test2 on test1.x = test2.x;
执行计划如下:

如上执行计划,test2
表只有1000行,test1
表有100000行,build端和probe端的数据量比例是0.01小于0.1,且Join出来的数据量build端和probe端比例是0.01低于0.1,满足Runtime Filter的默认触发条件,因此引擎会自动使用Runtime Filter。同时在执行计划中,也可以看到probe端的test1
表有Runtime Filter Target Expr
节点,表示probe端使用了Runtime Filter下推。