GBase 8a数据库指定join顺序功能
支持用户指定join顺序功能
多表join连接顺序时,是基于规则的评估,并且优化规则在代码中是固定的,因此不能根据不同的需求灵活改变join的连接顺序。
开启_t_gcluster_user_defined_join_hint参数为1
1)通过hint join_path()功能来指定join的连接顺序,即需要gccli -uroot -c进入客户端,具体语法如下:
/+Join_path(‘tablename,tablename,[,...]’)/
/*+Join_path(‘(tablename,tablename),
[tablename][,tablename,tablename,[,...]’)]*/
支持嵌套使用,支持使用别名。
2)无论是否有括号,涉及两个及以上的表均按照书写顺序执行join;
如:join_path(‘a,b,c’)按照a,b,c顺序执行
3)当有多个括号时,先执行括号中的,再按书写顺序执行;
如:join_path(‘(a,b),c,(d,e)’),按照(a,b)->c->(d,e)执行
使用约束:必须指定当前select子句所使用的所有from子句中所有涉及到的表或子查询别名;一个join_path()只涉及当前select语句中from子句的表名或别名,若包含子查询,需要多个hint来指定不同select语句中from子句中的表或别名;仅对express表生效。
使用示例:
Gccli -uroot -c进入客户端
set global _t_gcluster_user_defined_join_hint=1 ;
set global gbase_sql_trace=on;
create table a(id1 int,id2 varchar(100),id3 char(2),id4 decimal,id5 timestamp,id6 int);
create table b(id1 int,id2 varchar(100),id3 char(2),id4 decimal,id5 timestamp,id6 int) distributed by ('id1');
create table c(id1 int,id2 varchar(100),id3 char(2),id4 decimal,id5 timestamp,id6 int) distributed by ('id1','id2');
insert into a values(2,'cdcodsds','aa',5435.234,'2020-03-20 12:00:00',45);
insert into a values(1,'cdcodsd','aa',5435.234,'2020-03-21 12:00:00',45);
insert into a values(20,'cdcods','aa',5435.234,'2020-03-22 12:00:00',45);
insert into a values(200,'cdcod','aa',5435.234,'2020-03-20 12:00:00',45);
insert into a select * from a;
insert into a select * from a;
insert into b values(2,'vferf','aa',584395870,'2020-03-20 13:00:00',54);
insert into b values(1,'vfef','bb',5435.234,'2020-03-23 13:00:00',54);
insert into b values(3,'cdcodsds','bb',584395870,'2020-03-22 13:00:00',54);
insert into b values(2,'cdcodsds','aa',5435.234,'2020-03-20 12:00:00',45);
insert into b select * from b;
insert into b select * from b;
insert into c values(2,'vferf','bb',5446,'2020-03-21 13:00:00',65);
insert into c values(3,'vfer','aa',5435.234,'2020-03-20 13:00:00',65);
insert into c values(1,'cdcodsds','bb',5446,'2020-03-21 13:00:00',65);
insert into c values(2,'cdcodsds','aa',5435.234,'2020-03-20 12:00:00',45);
insert into c select * from c;
insert into c select * from c;
select * from a join b join c on a.id1=b.id1 and b.id1=c.id1;
同一条查询语句,使用指定join顺序后,查看trace日志中jointree,可以看到join顺序已经按照指定的顺序执行:
-- 1
select /+join_path('a,b,c')/ * from a join b join c on a.id1=b.id1 and b.id1=c.id1;
-- 2
select /+join_path('a,c,b')/ * from a join b join c on a.id1=b.id1 and b.id1=c.id1;
-- 3
select /+join_path('b,a,c')/ * from a join b join c on a.id1=b.id1 and b.id1=c.id1;