在数据仓库中如何做分桶
- 为什么分桶
(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。
(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。
分区是粗粒度的划分,桶是细粒度的划分,为了让查询发生在更小范围的数据上来提高效率。分桶将整个数据内容安装某列属性值得hash值进行区分,如要安装name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。
与分区不同的是,分区依据的不是真实数据表文件中的列,而是我们指定的伪列,但是分桶是依据数据表中真实的列而不是伪列。所以在指定分区依据的列的时候要指定列的类型,因为在数据表文件中不存在这个列,相当于新建一个列。而分桶依据的是表中已经存在的列,这个列的数据类型显然是已知的,所以不需要指定列的类型。
- 如何做分桶
(1)创建表
create table if not exists testA
(
uuid string comment "UUID",
dat_at date comment "数据创建日期"
)
COMMENT "行为大宽表"
PARTITIONED BY (evt_id STRING)
CLUSTERED BY (dat_at) INTO 32 BUCKETS;
(2)设置参数
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.enforce.bucketing= true;
(3)插入数据
insert into table testA partition(evt_id)
select reflect('java.util.UUID', 'randomUUID'),
to_date(created_at),
'5'
from testB