Hadoop上的SQL技术:列式存储、Hive调优与Impala应用
立即解锁
发布时间: 2025-08-25 00:55:12 阅读量: 1 订阅数: 6 

### Hadoop 上的 SQL 技术:列式存储、Hive 调优与 Impala 应用
#### 1. 列式数据存储
在数据处理中,常见的数据存储方式是行式存储,像 CSV、SequenceFiles 和 Avro 通常都按行存储,即一行数据的所有列在持久存储时是连续存放的。不过,采用列式存储格式存储数据,能在空间和执行时间上带来显著的性能提升。
列式数据连续存放,使得存储格式可以运用复杂的数据压缩方案,例如游程编码,而行式数据则无法应用此类编码。此外,列式数据能让 Hive、MapReduce 和 Tez 等执行引擎将谓词和投影操作下推到存储格式,从而使存储格式能够跳过不符合下推条件的数据。
目前,在 Hive(和 Hadoop)上有两种热门的列式存储选项:
- **Optimized Row Columnar (ORC)**:由 Hortonworks 推出。
- **Parquet**:来自 Cloudera/Twitter。
这两种格式在节省空间和时间方面的优化效果相近,但 Parquet 旨在最大限度地提高在 Hadoop 社区的兼容性,因此在当前,它对 Hadoop 生态系统的支持更为广泛。
#### 2. 优化 Hive 连接操作
在 Hive 中对大型数据集执行连接操作时,往往需要花费数小时才能完成。下面介绍一些优化 Hive 连接的方法。
##### 2.1 创建示例表
在开始优化之前,先创建两个示例表:
```bash
$ hadoop fs -mkdir stocks-mini
$ hadoop fs -put test-data/ch9/stocks-mini.txt stocks-mini
$ hadoop fs -mkdir symbol-names
$ hadoop fs -put test-data/ch9/symbol-names.txt symbol-names
```
```sql
hive> CREATE EXTERNAL TABLE stocks (
symbol STRING,
date STRING,
open FLOAT
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/user/YOUR-USERNAME/stocks-mini';
hive> CREATE EXTERNAL TABLE names (
symbol STRING,
name STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
LOCATION '/user/YOUR-USERNAME/symbol-names';
```
`stocks` 表包含股票代码、日期和开盘价三列,`names` 表包含股票代码和公司名称。
##### 2.2 连接表顺序
Hive 执行连接操作时,需要选择哪个表进行流式处理,哪个表进行缓存。Hive 会选择 JOIN 语句中的最后一个表进行流式处理,所以应确保最后一个表是最大的表。例如,`stocks` 表会随着时间不断增长,而 `names` 表相对稳定,因此在连接时,应让 `stocks` 表在查询中最后出现:
```sql
SELECT stocks.symbol, date, open, name
FROM names
JOIN stocks ON (names.symbol = stocks.symbol);
```
也可以显式指定 Hive 进行流式处理的表:
```sql
SELECT /*+ STREAMTABLE(stocks) */ stocks.symbol, date, open, name
FROM names
JOIN stocks ON (names.symbol = stocks.symbol);
```
##### 2.3 映射端连接
复制连接属于映射端连接,它会将小表缓存在内存中,对大表进行流式处理。可以通过以下设置让 Hive 自动尝试将连接转换为映射端连接:
```sql
hive> set hive.auto.convert.join = true;
hive> SET hive.auto.convert.join.noconditionaltask = true;
hive> SET hive.auto.convert.join.noconditionaltask.size = 10000000;
```
前两个设置必须为 `true` 才能启用连接到映射端连接的自动转换(在 Hive 0.13 中,这两个设置默认启用)。最后一个设置用于判断连接是否可以转换,如果连接中最小的 N - 1 个表在磁盘上的大小小于 `hive.auto.convert.join.noconditionaltask.size`,则连接将转换为映射端连接。不过,这种检查比较简单,仅考虑表在磁盘上的大小,不涉及压缩、过滤或投影等因素。
在旧版本的 Hive 中,支持使用提示来指示 Hive 哪个表是最小的,应该进行缓存,例如:
```sql
SELECT /*+ MAPJOIN(names) */ stocks.symbol, date, open, name
FROM names
JOIN stocks ON (names.symbol = stocks.symbol);
```
但在新版本的 Hive 中,默认会忽略这个提示,因为它要求查询编写者确定较小的表,可能会因用户错误导致查询变慢。
##### 2.4 排序合并桶连接
Hive 表可以进行分桶和排序,这有助于数据采样,也是一种有效的连接优化方法,即排序合并桶(SMB)连接。SMB 连接要求所有表在连接列上进行排序和分桶,这样连接操作只需简单合并预排序的表,效率很高。
创建一个排序和分桶的 `stocks` 表示例:
```sql
CREATE TABLE stock
```
0
0
复制全文
相关推荐










