JOIN ELIMINATION
子表消除
功能描述
在查询语句中,支持对左外连接进行优化,消除不需要的右表,提升查询效率。使用该功能需设置GUC参数enable_je_enhanced为on,默认值为off。
注意事项
仅Vastbase G100 V2.2 Build 10(Patch No.17)及以后版本支持此功能。
子表消除要求左外连接需满足以下条件:
- 输出中指定了DISTINCT或者DISTINCT ON,连接条件为等值条件,且右表只被当前连接的连接条件引用。
- 左外连接所在语句中没有包含以下操作:GROUP BY、ROLLUP、ORDER BY、LIMIT、WINDOW FUNCTION、SEQUENCE、ROWNUM、VOLATILE函数、CTE、FOR…SHARED/UPDATE、LATERAL、CONNECT BY、UNION集合操作、聚集函数、半连接、返回结果为集合的函数和子句。
- 左外连接的左表和右表都是一个实体表,且右表列只在等值连接条件中被引用。
- 左外连接等值条件中的两侧分别引用左侧表列和右侧表列,且每个条件中都各引用一次。
- 仅支持针对FROM语句中只有一个外连接,且为左外连接的子表消除。
- 连接条件中不包含易失性函数(指没有相关数据变化的情况下回自动更新结果的函数,例如rand()、now()等)。
示例
1、创建测试表并插入测试数据。
create table test1_1200501(id int ,col1 text);
insert into test1_1200501 values(1,'a');
insert into test1_1200501 values(1,'b');
insert into test1_1200501 values(2,'c');
insert into test1_1200501 values(3,'d');
create table test2_1200501(id int ,col1 int);
insert into test2_1200501 values(1,100);
insert into test2_1200501 values(2,200);
insert into test2_1200501 values(2,300);
insert into test2_1200501 values(4,400);
2、查看符合子表消除条件的左外连接查询的执行计划。
EXPLAIN SELECT DISTINCT test1_1200501.* FROM test1_1200501 LEFT JOIN test2_1200501 ON test1_1200501.id = test2_1200501.id;
返回结果为:
QUERY PLAN
------------------------------------------------------------------------------------
HashAggregate (cost=290.37..292.37 rows=200 width=36)
Group By Key: test1_1200501.id, test1_1200501.col1
-> Hash Right Join (cost=37.86..223.86 rows=13302 width=36)
Hash Cond: (test2_1200501.id = test1_1200501.id)
-> Seq Scan on test2_1200501 (cost=0.00..31.49 rows=2149 width=4)
-> Hash (cost=22.38..22.38 rows=1238 width=36)
-> Seq Scan on test1_1200501 (cost=0.00..22.38 rows=1238 width=36)
(7 rows)
3、开启子表消除功能,查看步骤2中语句的执行计划。
SET enable_je_enhanced=on;
EXPLAIN SELECT DISTINCT test1_1200501.* FROM test1_1200501 LEFT JOIN test2_1200501 ON test1_1200501.id = test2_1200501.id;
返回结果为:
QUERY PLAN
------------------------------------------------------------------------
HashAggregate (cost=28.57..30.57 rows=200 width=36)
Group By Key: test1_1200501.id, test1_1200501.col1
-> Seq Scan on test1_1200501 (cost=0.00..22.38 rows=1238 width=36)
(3 rows)
步骤2执行计划中扫描了表test2_1200501和test1_1200501,在步骤3执行计划中仅扫描了test1_1200501,提高了查询效率。
4、清理测试数据。
SET enable_je_enhanced=off;
DROP TABLE test1_1200501;
DROP TABLE test2_1200501;