Bucket
以下这种创建表的方法是不限定 bucket。
create table t1(c1 string,...)
Hive Bucket 表是比分区更细粒度的文件组织方式。以下的方式创建 8 个 bucket。
create table t1(c1 string) [PARTITIONED BY (C2 STRING)]
CLUSTERED BY (C1) [SORTED BY (C1)] INTO 8 BUCKETS;
中括号‘[]’ 表示对应的内容是可选的。
SORTED BY 表示每个 bucket 内部按指定的字段有序。
Bucket 表的影响
insert overwrite
insert overwrite 到 非 bucket 表,可以没有 reduce。但是 insert overwrite 到 bucket 表,除非 from 的表也是 bucket 表,并且 bucket 的数量和 目标表的 bucket 数量有倍数关系,否则需要 reduce,并且 reduce 的数量自动等于 bucket 的数量。
CREATE TABLE test.`store_returns`(
`sr_return_time_sk` bigint,
`sr_item_sk` bigint,
`sr_customer_sk` bigint,
`sr_cdemo_sk` bigint,
`sr_hdemo_sk` bigint,
`sr_addr_sk` bigint,
`sr_store_sk` bigint,
`sr_reason_sk` bigint,
`sr_ticket_number` bigint,
`sr_return_quantity` int,
`sr_return_amt` decimal(7,2),
`sr_return_tax` decimal(7,2),
`sr_return_amt_inc_tax` decimal(7,2),
`sr_fee` decimal(7,2),
`sr_return_ship_cost` decimal(7,2),
`sr_refunded_cash` decimal(7,2),
`sr_reversed_charge` decimal(7,2),
`sr_store_credit` decimal(7,2),
`sr_net_loss` decimal(7,2),
`sr_returned_date_sk` bigint)
CLUSTERED BY(sr_return_time_sk) INTO 256 BUCKETS;
以下语句任务的会有 256 个 reduce。
insert overwrite table test.store_returns select * from tpcds_hdfs_orc_300.store_returns;
CREATE TABLE test.`store_returns2`(
`sr_return_time_sk` bigint,
`sr_item_sk` bigint,
`sr_customer_sk` bigint,
`sr_cdemo_sk` bigint,
`sr_hdemo_sk` bigint,
`sr_addr_sk` bigint,
`sr_store_sk` bigint,
`sr_reason_sk` bigint,
`sr_ticket_number` bigint,
`sr_return_quantity` int,
`sr_return_amt` decimal(7,2),
`sr_return_tax` decimal(7,2),
`sr_return_amt_inc_tax` decimal(7,2),
`sr_fee` decimal(7,2),
`sr_return_ship_cost` decimal(7,2),
`sr_refunded_cash` decimal(7,2),
`sr_reversed_charge` decimal(7,2),
`sr_store_credit` decimal(7,2),
`sr_net_loss` decimal(7,2),
`sr_returned_date_sk` bigint)
CLUSTERED BY(sr_return_time_sk) INTO 256 BUCKETS;
以下任务没有 reduce,只有 256 个 map 任务,因为 from 表和 to 表的 bucket 数量相等。
insert overwrite table test.store_returns2 select * from tpcds_hdfs_orc_300.store_returns;
select
=
对于按CLUSTERED BY 字段用=
判断的查询,可以只读取相应的 bucket的数据,加快程序的执行速度。
如以下语句仅用1个 map 读取其中一个 bucket 的数据。
select count(*) from test.store_returns
where store_returns.sr_return_time_sk = 33777;
非等于
由于数据分到哪个 bucket 是按 hash 算法,所以以下语句需要读取所有的 bucket。
select count(*) from test.store_returns
where store_returns.sr_return_time_sk > 33777;
Hive 3.1.0 的 bug
Hive 3.1.0 对于不等于,没有生成任何 map,是一个 bug。
select count(*) from test.store_returns
where store_returns.sr_return_time_sk <> 33777;