运行倾斜的hint
功能描述
指明查询运行时重分布过程中存在倾斜的重分布键和倾斜值,针对Join和HashAgg运算中的重分布进行优化。
语法格式
- 指定单表倾斜:
1
skew( [@queryblock] table (column) [(value)])
- 指定中间结果倾斜:
1
skew( [@queryblock] (join_rel) (column) [(value)])
参数说明
- @queryblock 见指定Hint所处的查询块Queryblock章节,可省略,表示在当前查询块生效。
- table表示存在倾斜的单个表名。
- join_rel表示参与join的两个或多个表,如(t1 t2)表示t1和t2join后的结果存在倾斜。
- column表示倾斜表中存在倾斜的一个或多个列。
- value表示倾斜的列中存在倾斜的一个或多个值。
- skew hint仅在需要重分布且指定的倾斜信息与查询执行过程中的重分布信息相匹配时才会被使用。
- skew hint受GUC参数skew_option限制,如果参数处于关闭状态,则无法进行skew hint倾斜调优。
- skew hint目前仅处理普通表和子查询类型的表关系,支持基表hint、子查询hint、with as子句hint。对于子查询,无论提升与否都支持在skew hint中使用,这点与其它hint不一样。
- 对于倾斜表,如果定义了别名,则在hint中必须使用别名。
- 对于倾斜列,在不产生歧义的情况下,可以使用原名也可以使用别名。skew hint的column不支持表达式,如果需要指定采用分布键为表达式的重分布存在倾斜,需要将重分布键指定为新的列,以新的列进行hint。
- 对于倾斜值,个数需为列数的整数倍并按列的顺序进行组合,组合的个数不能超过10个。如果各倾斜列的倾斜值的个数不一样,为了满足按列组合,值可以重复指定。如,表t1的c1和c2存在倾斜,c1列的倾斜值只有a1,而c2列的倾斜有b1和b2,则skew hint如下:skew(t1 (c1 c2) ((a1 b1)(a1 b2)))。例中(a1 b1)为一个值组合,NULL可以作为倾斜值出现,每个hint中的值组合不超过十个, 且需为列的整数倍。
- 在Join的重分布优化中,skew hint中的value不可缺省,在HashAgg中可以缺省。
- 对于表、列、值中若指定多个,则同类间需以空格分离。
- 对于倾斜值,不支持在hint中进行类型强转;对于string类型,需要使用单引号。
例如:
- 指定单表倾斜
每一个skew hint用来表示一个表关系存在的倾斜信息,如果想要指定在查询中的多个表关系存在的倾斜信息,则通过指定多个skew hint实现。
在指定skew时,包括以下四个场景的用法:
- 单列单值: skew(t (c1) (v1))
- 单列多值:skew(t (c1) (v1 v2 v3 ...))
- 多列单值:skew(t (c1 c2) (v1 v2))
- 多列多值:skew(t (c1 c2) ((v1 v2) (v3 v4) (v5 v6) ...))
说明:表关系t的c1列的v1、v3、v5…值和c2列的v2、v4、v6…值在查询执行中存在倾斜。
多列多值时,各组倾斜值间也可以不使用括号,如:skew(t (c1 c2) (v1 v2 v3 v4 v5 v6 ...))。是否使用括号必须统一,不可混合,
如:skew(t (c1 c2) (v1 v2 v3 v4 (v5 v6) ...)) 将会产生语法报错。
- 指定中间结果倾斜
如果基表不存在倾斜,而是查询执行中的中间结果出现倾斜,则需要通过指定中间结果倾斜的skew hint来进行倾斜的调优。skew((t1 t2) (c1) (v1))
说明:表关系t1和t2 Join后的结果存在倾斜,倾斜的是t1表的c1列,c1列的倾斜值是v1。
为了避免产生歧义,“c1”只能存在于join_rel的一个表关系中,如果存在同名列则通过别名进行规避。
建议
- 如果查询具有多层,则哪一层出现倾斜,则将hint写在哪一层中。
- 对于提升的子查询,skew hint支持直接使用子查询名进行hint。如果明确子查询提升后的哪一个基表存在倾斜,则直接使用基表进行hint的可用性更高。
- 无论对于表或列,若存在别名,则优先使用别名进行hint。