暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

GBase 8a MPP Cluster 关联场景优化策略

原创 上善若水 2022-06-08
415

1.1.1 关联优化

1.1.1.1   JOIN关联优化策略

逐个排查右表,对于右表是分布表且破坏hash分布的,如果数据量小,直接修改为复制表,避免将大表进行拉表操作;如果数据量大(1亿以上的),通过调整gcluster_hash_redistribute_join_optimize参数进行验证,参数说明如下: 

set gcluster_hash_redistribute_join_optimize=0|1|2 

    0 -- 拉复制表 

    1 -- 重分布 

    2 -- 自动评估,根据数据量,左右表行数接近使用重分布,如果差距大,则小表拉复制表 。

注1:遇到 left join 语句时,评估右表是否建为复制的原则是:

(1)如果右表的字段不大于10个,且记录数不大于5000万行,则右表创建为复制表;

(2)如果右表字段数大于10个,且记录数不大于1000万,则右表创建为复制表

V1.1 add:注2:当设置为自动评估时,可以设置多少行以上才进行hash重分布,设置参数为gcluster_hash_redist_threshold_row=xxxx。

1.1.1.2  关联顺序优化

优化原因

    GCluster的优化器不会调整LEFT JOIN语句的顺序,而用户语句的JOIN顺序可能不是最优,导致查询性能较低。

SQL特征

语句包含多个LEFT JOIN

多个LEFT JOIN的ON条件均为t1.colX = tn.colX

如:select x1.* from x1

    left join x2 on x1.many_duplicate_value = x2.many_duplicate_value

    left join x3 on x1.no_duplicate_value = x3.no_duplicate_value

    left join x4 on x1.hash_col = x4.hash_col;

优化场景

语句特征满足上面的特征描述。

LEFT JOIN的右表,一些表可以直接与左表形成Hash JOIN关系,一些表可能会导致左表发生膨胀。

优化效果

让形成Hash JOIN关系的LEFT JOIN先执行,避免拉表。

例如SQL特征中描述的语句,因为left join x4 on x1.hash_col = x4.hash_col是Hash分布式JOIN,因此可以提到最前面,直接分布式执行。

让膨胀率小的LEFT JOIN先执行,减小拉表数据量。

如果参与JOIN条件的列的值的重复度较高,则很可能会造成LEFT JOIN结果发生膨胀。一般来说,使用主键列参与的JOIN条件,膨胀率是最小的;而重复值越多的列,膨胀率就越可能高。

例如SQL特征中描述的语句,因left join x3 on x1.no_duplicate_value = x3.no_duplicate_value对x1的膨胀率比left join x2 on x1.many_duplicate_value = x2.many_duplicate_value小,因此可以把left join x3提到left join x2前面。

通过这种调整,避免对膨胀后的数据拉表,减小了拉表数据量。

示例语句

select x1.* from x1

left join x2 on x1.many_duplicate_value = x2.many_duplicate_value

left join x3 on x1.no_duplicate_value = x3.no_duplicate_value

left join x4 on x1.hash_col = x4.hash_col;

改写后语句

select x1.* from x1

left join x4 on x1.hash_col = x4.hash_col;

left join x3 on x1.no_duplicate_value = x3.no_duplicate_value

left join x2 on x1.many_duplicate_value = x2.many_duplicate_value

注:因x1.hash_col = x4.hash_col使用Hash分布列,因此left join x4调整到第1个位置;因x1.no_duplicate_value = x3.no_duplicate_value的膨胀率比x1.many_duplicate_value = x2.many_duplicate_value的膨胀率低,因此把left join x3调整到left join x2之前。

1.1.1.3   关联条件优化

案例1-关联条件的顺序优化

优化原因:

当前版本的GNode中,LEFT JOIN的ON条件中的右表单表条件会在JOIN之后执行,尤其当LEFT JOIN的右表是大表时,会导致参与JOIN的数据量过大,增加JOIN耗时。

SQL特征

LEFT JOIN语句

ON条件中包含右表的单表条件

优化场景

LEFT JOIN的右表是大表

ON条件中,右表的单表条件过滤后的数据量占右表总数据量比较少(约10%左右)。

注:因为本优化改写是把右表改写为子查询,需要考虑子查询额外的物化消耗,因此不是所有此类SQL改写都能提升性能,尤其是当查询的投影列中出现大量右表列时。

优化效果

通过改写,把右表单表过滤放在一个独立的子查询中,保证右表的过滤在JOIN前执行,达到优化查询性能的目的。

示例语句:

select x1.id2, x2.id2, x2.id3 from x1 left join x2 on x1.id2 = x2.id2 and x2.id3 = 301;

改写后语句

    select x1.id2, x2.id2, x2.id3 from x1 left join (select x2.id2, x2.id3 from x2 where x2.id3 = 301) x;

 

案例2-关联条件带有子查询的优化

优化原因

GNode中,LEFT JOIN的ON条件中的相关子查询无法按优化方式执行,需要按逐行代入方式执行,这导致相关子查询的执行性能极低。

SQL特征

LEFT JOIN语句

ON条件中包含右表的单表条件,且这个单表条件是一个相关子查询

Trace信息

相关子查询无法按优化方式执行时,GNode的trace中会有如下信息:

can't optimize this subselect because OUTER JOIN or "outer select's table is used in having" or ... !

示例语句

select x1.id2, x2.id2, x2.id3 from x1 left join x2 on x1.id2 = x2.id2 and exists (select 1 from x3 where x3.id3 = x2.id3);

改写后语句

select x1.id2, x.id2, x.id3 from x1 left join (select id2, id3 from x2 where exists (select 1 from x3 where x3.id3 = x2.id3)) x on x1.id2 = x.id2;

 

案例3-通过新增关联条件字段,提高性能

当SQL语句中用到表内关联的计算时候,尤其是表的数据量超千万级别的时候,可以尝试将关联计算创建为一个字段,通过新字段结果进行直接判断。

举例:

    select

        …

        …

    from rep.statcmain a ,rep.statcitemkind b,

    where 表关联条件

    and a.statdate <= a.endstatdate

    and ..

表rep.statcmain数据量为81864314,当表内关联计算比较a.statdate与a.endstatdate的大小时,耗时长,修改为如下两步进行优化,

 

首先在rep.statcmain上创建数值型字段 statdate_endstatdate。

令statdate_endstatdate= a.statdate- a.endstatdate。

update rep.statcmain set statdate_endstatdate = cast(statdate as date) - cast(endstatdate as date);

 

表关联的时候通过statdate_endstatdate字段过滤数据。

    select

        …

        …

    from rep.statcmain a ,rep.statcitemkind b,

    where 表关联条件

      and statdate_endstatdate <= 0

      and ..

性能对比:优化前执行1小时50分钟,优化后执行45分钟。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论