hive HQL

本文详细介绍了HiveSQL中的各种数据表创建、分区、分桶、数据加载、联合查询、自定义函数以及使用脚本批量执行HQL语句的方法,展示了Hive在大数据处理中的关键操作。

set hive.cli.print.header=true;

CREATE TABLE page_view(viewTime INT, userid BIGINT,
     page_url STRING, referrer_url STRING,
     ip STRING COMMENT 'IP Address of the User')
 COMMENT 'This is the page view table'
 PARTITIONED BY(dt STRING, country STRING)
 ROW FORMAT DELIMITED
   FIELDS TERMINATED BY '\001'
STORED AS SEQUENCEFILE;   TEXTFILE

//sequencefile
create table tab_ip_seq(id int,name string,ip string,country string) 
    row format delimited
    fields terminated by ','
    stored as sequencefile;
insert overwrite table tab_ip_seq select * from tab_ext;


//create & load
create table tab_ip(id int,name string,ip string,country string) 
    row format delimited
    fields terminated by ','
    stored as textfile;
load data local inpath '/home/hadoop/ip.txt' into table tab_ext;

//external
CREATE EXTERNAL TABLE tab_ip_ext(id int, name string,
     ip STRING,
     country STRING)
 ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
 STORED AS TEXTFILE
 LOCATION '/external/hive';
 

// CTAS  用于创建一些临时表存储中间结果
CREATE TABLE tab_ip_ctas
   AS
SELECT id new_id, name new_name, ip new_ip,country new_country
FROM tab_ip_ext
SORT BY new_id;


//insert from select   用于向临时表中追加中间结果数据
create table tab_ip_like like tab_ip;

insert overwrite table tab_ip_like
    select * from tab_ip;

//CLUSTER <--相对高级一点,你可以放在有精力的时候才去学习>
create table tab_ip_cluster(id int,name string,ip string,country string)
clustered by(id) into 3 buckets;

load data local inpath '/home/hadoop/ip.txt' overwrite into table tab_ip_cluster;
set hive.enforce.bucketing=true;
insert into table tab_ip_cluster select * from tab_ip;

select * from tab_ip_cluster tablesample(bucket 2 out of 3 on id); 

//PARTITION
create table tab_ip_part(id int,name string,ip string,country string) 
    partitioned by (part_flag string)
    row format delimited fields terminated by ',';
    
load data local inpath '/home/hadoop/ip.txt' overwrite into table tab_ip_part
     partition(part_flag='part1');
    
    
load data local inpath '/home/hadoop/ip_part2.txt' overwrite into table tab_ip_part
     partition(part_flag='part2');

select * from tab_ip_part;

select * from tab_ip_part  where part_flag='part2';
select count(*) from tab_ip_part  where part_flag='part2';


alter table tab_ip change id id_alter string;
ALTER TABLE tab_cts ADD PARTITION (partCol = 'dt') location '/external/hive/dt';

show partitions tab_ip_part;


   
//write to hdfs
insert overwrite local directory '/home/hadoop/hivetemp/test.txt' select * from tab_ip_part where part_flag='part1';    
insert overwrite directory '/hiveout.txt' select * from tab_ip_part where part_flag='part1';

//array 
create table tab_array(a array<int>,b array<string>)
row format delimited
fields terminated by '\t'
collection items terminated by ',';

示例数据
tobenbrone,laihama,woshishui     13866987898,13287654321
abc,iloveyou,itcast     13866987898,13287654321


select a[0] from tab_array;
select * from tab_array where array_contains(b,'word');
insert into table tab_array select array(0),array(name,ip) from tab_ext t; 

//map
create table tab_map(name string,info map<string,string>)
row format delimited
fields terminated by '\t'
collection items terminated by ';'
map keys terminated by ':';

示例数据:
fengjie            age:18;size:36A;addr:usa
furong        age:28;size:39C;addr:beijing;weight:180KG


load data local inpath '/home/hadoop/hivetemp/tab_map.txt' overwrite into table tab_map;
insert into table tab_map select name,map('name',name,'ip',ip) from tab_ext; 

//struct
create table tab_struct(name string,info struct<age:int,tel:string,addr:string>)
row format delimited
fields terminated by '\t'
collection items terminated by ','

load data local inpath '/home/hadoop/hivetemp/tab_st.txt' overwrite into table tab_struct;
insert into table tab_struct select name,named_struct('age',id,'tel',name,'addr',country) from tab_ext;


//cli shell
hive -S -e 'select country,count(*) from tab_ext' > /home/hadoop/hivetemp/e.txt  
有了这种执行机制,就使得我们可以利用脚本语言(bash shell,python)进行hql语句的批量执行


select * from tab_ext sort by id desc limit 5;

select a.ip,b.book from tab_ext a join tab_ip_book b on(a.name=b.name);


//UDF
0.要继承org.apache.hadoop.hive.ql.exec.UDF类实现evaluate

自定义函数调用过程:
1.添加jar包(在hive命令行里面执行)
hive> add jar /root/NUDF.jar;

2.创建临时函数
hive> create temporary function getNation as 'cn.itcast.hive.udf.NationUDF';

3.调用
hive> select id, name, getNation(nation) from beauty;

4.将查询结果保存到HDFS中
hive> create table result row format delimited fields terminated by '\t' as select * from beauty order by id desc;    
hive> select id, getAreaName(id) as name from tel_rec;
hive>create table result row format delimited fields terminated by '\t' as select id, getNation(nation) from beauties;
hive>select if(id=1,first,no-first),name from tab_ext;
hive>add jar /home/hadoop/myudf.jar;
hive>CREATE TEMPORARY FUNCTION my_lower AS 'org.dht.Lower';
hive>select my_upper(name) from tab_ext;  


 

<think> 我们讨论的是Hive HQLHive Query Language),它是基于SQL的,但针对Hadoop生态系统进行了扩展和优化。用户的问题集中在HQL中如何处理数据倾斜,以及如何解释HQL中编写如随机数分散Key、MapJoin、分组聚合优化等代码的能力。同时,用户希望澄清HQL与SQL的关系,说明HQL是可以直接写SQL的(因为HQL本质上是SQL的一种方言)。 根据之前的引用内容,我们知道HQL在分组聚合时可能遇到数据倾斜问题,而优化方法包括使用随机数分散Key、MapJoin、分组聚合优化、倾斜值单独处理等。这些优化技巧虽然在标准SQL中可能不常见,但在HQL中是允许的,因为Hive提供了这些扩展功能。 因此,我们需要解释: 1. HQL本质上是一种SQL方言,所以可以直接编写SQL语句,但Hive提供了更多针对大数据处理的扩展功能。 2. 为什么需要这些优化技巧(处理数据倾斜)。 3. 这些优化技巧在HQL中的具体实现方式(如代码示例)。 同时,根据用户提供的引用,我们可以得知: - 引用[1]和[3]说明了分组聚合的数据倾斜问题及原因。 - 引用[2]提到了随机数生成在Hive中的应用。 - 引用[4]则展示了一些Hive内置的虚拟列,这些也是HQL的扩展。 因此,我们可以这样组织回答: 一、HQL与SQL的关系 - HQL是SQL的一种方言,因此支持大多数标准SQL语法。同时,Hive为了应对大数据处理的特殊场景(如数据倾斜),扩展了一些功能,使得我们可以在HQL中编写一些特殊的优化技巧。 二、数据倾斜优化技巧的代码示例及原因 1. 随机数分散Key(用于分组聚合优化) - 原因:当分组字段的某个值特别多时,会导致一个Reduce任务处理的数据量过大,从而产生数据倾斜。通过给key添加随机前缀,将原本一个key的数据分散到多个key,然后在Reduce阶段进行二次聚合。 - 代码示例(来自引用[1]): ```sql -- 优化前:可能倾斜 SELECT key, count(1) FROM table GROUP BY key; -- 优化后:先给key加上随机前缀(0~99),进行第一次聚合,再去掉前缀进行第二次聚合 SELECT split(tmp.key, '_')[1] AS key, SUM(tmp.cnt) AS cnt FROM ( SELECT concat(cast(floor(rand()*100) as string), '_', key) AS key, count(1) AS cnt FROM table GROUP BY concat(cast(floor(rand()*100) as string), '_', key) ) tmp GROUP BY split(tmp.key, '_')[1]; ``` 2. MapJoin(处理Join倾斜) - 原因:当Join操作中有一个表很小,而另一个表很大且key分布不均时,可以将小表加载到内存中,直接在Map端完成Join操作,避免Shuffle和Reduce阶段,从而避免数据倾斜。 - 代码示例(设置自动MapJoin): ```sql -- 设置自动MapJoin set hive.auto.convert.join=true; -- 设置小表阈值 set hive.mapjoin.smalltable.filesize=25000000; -- 25MB -- 然后正常写Join语句,Hive会自动判断是否使用MapJoin SELECT /*+ MAPJOIN(small_table) */ big_table.key, small_table.value FROM big_table JOIN small_table ON big_table.key = small_table.key; ``` 3. 分组聚合优化(Combiner预聚合) - 原因:在Map端先进行局部聚合(Combiner),减少Shuffle的数据量。Hive默认会进行Map端聚合优化(hive.map.aggr=true)。 4. 倾斜值单独处理 - 原因:如果某个key的数据量特别大,我们可以将它单独拿出来处理,然后用union all合并结果。 - 代码示例: ```sql -- 假设key='skew_key'的数据倾斜 SELECT key, count(1) AS cnt FROM table WHERE key != 'skew_key' GROUP BY key UNION ALL SELECT 'skew_key' AS key, count(1) AS cnt FROM table WHERE key = 'skew_key'; ``` 三、为什么HQL可以这样写? - Hive作为大数据处理工具,其HQL语言在标准SQL的基础上,提供了更多的扩展功能(如UDF、虚拟列、优化Hint等)以应对分布式计算中的特殊问题(如数据倾斜)。因此,我们可以在HQL中使用随机数、MapJoin提示、union all等技巧来优化查询。 四、澄清:HQL与普通SQL的关系 - HQL是SQL的一种,所以可以直接编写标准SQL语句。同时,Hive提供了扩展功能,使得我们可以编写一些针对性的优化代码(如上述技巧),这些代码在标准SQL中可能不被支持,但在Hive中是被允许且有效的。 最后,生成相关问题。 注意:引用文献标记要放在相关段落末尾,用[^n]格式。 </think> ### Hive HQL 中特殊优化技巧的解析与 SQL 关系说明 #### 一、HQL 与 SQL 的关系澄清 1. **本质一致性** Hive HQL **本质是 SQL 方言**,完全支持标准 SQL 语法结构(如 `SELECT/JOIN/GROUP BY`)。用户可直接编写标准 SQL 语句执行数据处理[^4]。 2. **特殊优化扩展** Hive 为应对**大数据分布式计算场景**(如 MapReduce/Spark),在 HQL 中扩展了独有的优化语法: ```mermaid graph LR A[标准SQL语法] --> B[Hive特有扩展] B --> C[随机数分散Key] B --> D[MapJoin优化] B --> E[倾斜值拆分处理] ``` --- #### 二、特殊优化技巧的编写原理 ##### 1. 随机数分散 Key(解决分组聚合倾斜) **问题本质** 当分组字段(如 `user_id`)存在**热点值**(某用户订单量极大),会导致 Reduce 节点负载不均[^1][^3]。 **优化代码示例**: ```sql SELECT split(tmp_key, '_')[1] AS real_key, -- 还原原始Key SUM(cnt) AS total FROM ( SELECT concat(cast(rand()*100 as int), '_', key) AS tmp_key, -- 添加随机前缀 count(1) AS cnt FROM orders GROUP BY concat(cast(rand()*100 as int), '_', key) -- 首次聚合分散到多Reduce ) tmp GROUP BY split(tmp_key, '_')[1] -- 二次聚合 ``` **原理说明**: - 通过 `rand()` 生成随机前缀(0-99),将原 Key 转化为 `12_user1`, `85_user1` 等临时 Key - 首次聚合使热点数据**分散到多个 Reduce 节点** - 二次聚合时去掉前缀得到最终结果 ##### 2. MapJoin 处理倾斜(解决 Join 倾斜) **优化代码**: ```sql SET hive.auto.convert.join=true; -- 启用MapJoin优化 SET hive.mapjoin.smalltable.filesize=25000000; -- 小表阈值25MB /*+ MAPJOIN(small_table) */ SELECT large_table.id, small_table.name FROM large_table JOIN small_table ON large_table.id = small_table.id; ``` **实现原理**: - 将小表全量加载到**每个 Mapper 的内存**中 - 大表数据在 Map 阶段直接完成 Join - 避免 **Shuffle 数据倾斜**(引用[3]描述的瓶颈场景) ##### 3. 倾斜值单独处理(极端热点分离) **代码示例**: ```sql -- 步骤1:正常处理非倾斜数据 SELECT key, count(1) AS cnt FROM table WHERE key NOT IN ('hot_value1','hot_value2') GROUP BY key UNION ALL -- 步骤2:单独处理倾斜值 SELECT key, count(1) AS cnt FROM table WHERE key IN ('hot_value1','hot_value2') GROUP BY key ``` **设计思想**: - 分离热点数据(如 `hot_value1`)单独计算 - 利用 **UNION ALL 并行执行**特性 - 避免单个 Reduce 处理超大数据块(引用[1]描述的分区问题) --- #### 三、HQL 扩展功能的底层支持 ##### 1. 虚拟列机制 Hive 提供特殊虚拟列辅助优化: ```sql SELECT INPUT__FILE__NAME, -- 数据所在文件名 BLOCK__OFFSET__INSIDE__FILE, -- 行偏移量 col1 FROM table ``` 通过 `set hive.exec.rowoffset=true` 启用后,可精确定位数据位置[^4],用于: - 数据采样优化 - 热点分区识别 - 调试执行计划 ##### 2. 分布式执行模型 $$\begin{array}{c} \text{Map阶段} \\ \downarrow \\ \text{Shuffle(数据分发)} \\ \downarrow \\ \text{Reduce阶段} \\ \end{array}$$ 所有优化技巧均围绕**避免 Shuffle 阶段数据倾斜**设计(引用[3]核心问题) ##### 3. 函数扩展能力 支持在 SQL 中直接调用分布式计算函数: ```sql SELECT rand(), -- 生成随机数[^2] percentile_approx(value, 0.5) -- 分布式分位数计算 FROM table ``` --- #### 四、标准 SQL 与 HQL 的兼容关系 | 特性 | 标准 SQL | Hive HQL | |--------------------|---------------|------------------| | 基础语法 | ✅ 完全支持 | ✅ 完全支持 | | 复杂 Join | ✅ 支持 | ✅ 支持(需优化) | | 自定义函数 | ❌ 有限支持 | ✅ 完全支持 | | 虚拟列 | ❌ 不支持 | ✅ 支持[^4] | | 分布式优化 Hint | ❌ 不支持 | ✅ 支持(如MapJoin)| | 倾斜值处理语法 | ❌ 不支持 | ✅ 特有扩展 | > **核心结论**:HQL 是标准 SQL 的超集,在完全兼容 SQL 语法基础上,扩展了**分布式计算优化语法**,两者非对立关系。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小哭包

创作不易,给作者加个鸡腿吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值