EsgynDB支持在两表hash join时使用min_max谓词来减少scan数据量,进而提升性能。举例来说,一个典型场景如下:
create table t1(c1 int primary key, c2 int, c3 int); create table t2(c1 int primary key, c2 int, c3 int); upsert using load into t1 select element,element,element from udf(series(1,100000)); upsert using load into t2 select element,element,element from udf(series(99000,199000)); update statistics for table t1 on every column sample; update statistics for table t2 on every column sample; |
此时考察如下sql语句的执行计划,是一个典型的两表hash join操作。分别将t1和t2表的数据完全扫描出来,并在内存中进行hash匹配。但是在当前场景中,第一张表的数据范围是1-100000,第二张表的数据范围是99000-199000,实际重叠范围仅有1000行左右。如果能够提前判断出这个范围,对t2就不需要进行全表扫描,只扫描1-100000范围内的1000行即可。这样就减少了扫描数据量,提高了性能。
在EsgynDB中,打开这个优化需要执行如下cqd:
cqd GEN_HSHJ_MIN_MAX_OPT 'on'; |
此时优化器会自动判断当前语句是否适合该优化。对第一张表扫描后取出最大和最小值,再将这个最大最小值推到第二张表的scan算子中,进而优化性能。如果再使用explain语句查看详细的执行计划,出现min_max_cols,min_max_hostvars等字段,则说明该优化成功开启。
最后查看一下优化开启前后的执行效率对比。优化开启前这条语句大约需要500多ms。(使用cqd last0_mode ‘on’来关闭打印,避免终端打印造成的影响)
开启优化后则只需要300多ms。 可以观察到性能明显的提升。性能提升幅度由min_max范围决定。假设两张表min_max范围几乎一直,无法过滤掉数据,则不会有性能提升。若可以过滤很多数据,则性能提升明显。