hive Hql

创建表
hive> CREATE TABLE pokes (foo INT, bar STRING);

创建表并创建索引字段ds
hive> CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING);

显示所有表
hive> SHOW TABLES;

按正条件(正则表达式)显示表,
hive> SHOW TABLES '.*s';

表添加一列
hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);

添加一列并增加列字段注释
hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');

更改表名
hive> ALTER TABLE events RENAME TO 3koobecaf;

删除表
hive> DROP TABLE pokes;

元数据存储:

将文件中的数据加载到表中
hive> LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE pokes;

加载本地数据,同时给定分区信息
hive> LOAD DATA LOCAL INPATH './examples/files/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');

加载DFS数据 ,同时给定分区信息
hive> LOAD DATA INPATH '/user/myname/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');

The above command will load data from an HDFS file/directory to the table. Note that loading data from HDFS will result in moving the file/directory. As a result, the operation is almost instantaneous.

SQL 操作:

按先件查询
hive> SELECT a.foo FROM invites a WHERE a.ds='<DATE>';

将查询数据输出至目录
hive> INSERT OVERWRITE DIRECTORY '/tmp/hdfs_out' SELECT a.* FROM invites a WHERE a.ds='<DATE>';

将查询结果输出至本地目录
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/local_out' SELECT a.* FROM pokes a;

选择所有列到本地目录
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;
hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/reg_3' SELECT a.* FROM events a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_4' select a.invites, a.pokes FROM profiles a;
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT COUNT(1) FROM invites a WHERE a.ds='<DATE>';
hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT a.foo, a.bar FROM invites a;
hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/sum' SELECT SUM(a.pc) FROM pc1 a;

将一个表的统计结果插入另一个表中
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar, count(1) WHERE a.foo > 0 GROUP BY a.bar;
hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(1) FROM invites a WHERE a.foo > 0 GROUP BY a.bar;

JOIN

hive> FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;


将多表数据插入到同一表中
FROM src
INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100
INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200
INSERT OVERWRITE TABLE dest3 PARTITION(ds='2008-04-08', hr='12') SELECT src.key WHERE src.key >= 200 and src.key < 300
INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dest4.out' SELECT src.value WHERE src.key >= 300;

将文件流直接插入文件
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09';

This streams the data in the map phase through the script /bin/cat (like hadoop streaming). Similarly - streaming can be used on the reduce side (please see the Hive Tutorial or examples)


实际示例:

创建一个表
CREATE TABLE u_data (
userid INT,
movieid INT,
rating INT,
unixtime STRING)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;

下载示例数据文件,并解压缩
wget http://www.grouplens.org/system/files/ml-data.tar__0.gz
tar xvzf ml-data.tar__0.gz

加载数据到表中
LOAD DATA LOCAL INPATH 'ml-data/u.data'
OVERWRITE INTO TABLE u_data;

统计数据总量
SELECT COUNT(1) FROM u_data;

现在做一些复杂的数据分析
创建一个 weekday_mapper.py: 文件,作为数据按周进行分割
import sys
import datetime
for line in sys.stdin:
line = line.strip()
userid, movieid, rating, unixtime = line.split('\t')

生成数据的周信息
weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()
print '\t'.join([userid, movieid, rating, str(weekday)])

使用映射脚本
//创建表,按分割符分割行中的字段值
CREATE TABLE u_data_new (
userid INT,
movieid INT,
rating INT,
weekday INT)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t';

//将python文件加载到系统
add FILE weekday_mapper.py;

将数据按周进行分割
INSERT OVERWRITE TABLE u_data_new
SELECT

TRANSFORM (userid, movieid, rating, unixtime)
USING 'python weekday_mapper.py'
AS (userid, movieid, rating, weekday)
FROM u_data;
SELECT weekday, COUNT(1)
FROM u_data_new
GROUP BY weekday;

<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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值