表的格式如下:
create table T(a, b, c,..., x) partitioned by (ds);
想要以下查询执行的更快。
select ... from T where ds = '20220310' and x = 10;
x 的基数 1000,但是 ds = ‘20220310’ 这个分区中, x=10,20,30,40 占总记录数的 90%,其余占10%。
在其它日期的数据也是类似,少数 x 值占绝大部分数据,但不一定是 10,20,30,40。
解决方法:
- 设置表的格式为 bucket 表
如果设置表的格式为 bucket 表,查找的时候仅需要查找相应的 bucket,比不设 bucket 查找的数据量少。但是如果总数据量很大,需要设置 bucket 的数量比较多,x = 10,20,30,40 有占记录的绝大部分,这四个值所在的 bucket 数据量很大,其他的 bucket 数据量很少。如果查询x 的值位于数据量多的 bucket,也需要读很多不需要的数据。所以此方法不理想。设置 ds 和 x 两层分区表
导致每天 1000 个分区,导致 metastore 压力大。绝大部分分区内文件小,导致 Namenode 压力大。设置表给 Skewed(数据倾斜的) 表。
Skewed Table(倾斜表):(倾斜表)是带倾斜信息的表。List Bucketing Table(Bucket 列表的表):首先是倾斜表,然后带 bucket 列表信息。 创建
CREATE TABLE(SCHEMA) SKEWED BY (KEYS) ON ('C1', 'C2') [STORED AS DIRECTORY]
例如:
create table T(c1 string, c2 string( skewed by (c1) on ('x1') stored as directories;
create table T(c1 string, c2 string( skewed by (c1, c2) on (('x1','x2'),('y1,y2')) stored as directories;
stored as directories 是可选的,他的作用是为倾斜的值创建子目录。
如第 1 个 SQL,c1=x1 的记录放在一个目录里,其他记录放在另一个目录里。
ALTER TABLE(SCHEMA) SKEWED BY (keys) on ('C1', 'C2') [STORED AS DIRECTORY];
本语句只可以在表级别,不能在分区级别。
他会吧一个普通的表转为一个倾斜的表,或者修改一个倾斜表的倾斜的字段信息。
删除删除一个表的倾斜信息
ALTER TABLE(SCHEMA) NOT SKEWED;
作用:
- 关掉一个表的倾斜的特性是一个表变成非倾斜的关掉 bucket 列表特性只会影响本语句执行之后的分区。之前的分区还是不受影响。
ALTER TABLE(SCHEMA) NOT STORED AS DIRECTORIES
关掉 bucket 列表功能,但是不关闭倾斜功能。
Alter Table Set Skewed LocationALTER TABLE(SCHEMA) SET SKEWED LOCATION(key1='loc1',key2='loc2');
改变 bucket 列表的位置映射。



