[Hive]Hive中表连接的优化,加快查询速度

本文介绍了Hive查询优化的关键方法,包括多表连接的执行顺序调整、JOIN连接时表顺序的选择、连接前通过WHERE过滤数据以及map-side JOIN优化等。通过这些技巧可以显著提升Hive查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、多表连接的执行顺序和MapReduce job优化

select
    a.ymd
    ,a.price_close
    ,b.price_close
    ,c.price_close
from stocks a join stocks b on a.ymd = b.ymd
              join stocks c on a.ymd = c.ymd
where a.symbol = 'APPL' and b.symbol = 'IBM' and c.symbol = 'GE'

 

大多数情况下Hive会对每对 JOIN 连接对象启动一个MapReduce任务。上例中会首先启动一个MapReduce job对表 a 和表 b 进行连接操作,
然后会启动一个MapReuce job将第一个MapReduce job的输出和表 c 进行连接操作。

当对3个或者更多个表进行 JOIN 连接时,如果每个 ON 子句都使用相同的连接键的话,那么只会产生一个 Map Reduce job。
即Hive通过一个优化可以在同一个Map Reduce job 中连接多个表(需要每个子句中有相同的连接键)。

2、JOIN连接时表的顺序(内连接)
Hive假定查询中最后一个表是最大的那个表,在对每行记录进行连接操作时,它会尝试将其他表缓存起来,然后扫描最后那个表进行计算。
因此用户需要保证连续查询中表的大小从左往右是依次增加的。

用户也可以人为显示告诉查询优化器哪张表是大表,即使它在查询中不是位于最后面的,使用方式如下:

select /*+STREAMTABLE(s)*/s.ymd, s.symbol,s.price_close,d.dividend
from stocks s JOIN dividends d ON s.ymd = d.ymd and s.symbol = d.symbol
where s.symbol='APPL'

3、连接前通过WHERE过滤数据加快查询数据
最直接了当的方式是使用嵌套SELECT语句:

select 
    s.ymd,s.symbol,s.price_close,d.dividends 
from 
    (
        select * from stocks 
        where symbol = 'AAPL' and exchange = 'NASDAQ'
    )s
left outer join
    (
        select * from dividends 
        where symbol = 'AAPL' and exchange = 'NASDAQ'
    )d
on s.ymd = d.ymd

4、map-side JOIN 优化含有小表的连接
如果所有表中只有一张表是小表,则可以在最大的表通过mapper的时候将小表完全放到内存中。Hive可以在map端执行连接过程(称为mao-side JOIN),这是因为
Hive可以和内存中的小表逐一匹配,从而省略常规连接操作需要的reduce过程。不仅减少了reduce过程,有时也可以同时减少map过程的执行步骤。

set hive.auto.convert.join=true; --让Hive在必要的时候启动优化
hive.mapjoin.smalltable.filesize=25000000; --设置能够使用这个优化的小表的大小(单位是字节)

 

### Hive 查询性能优化方法 #### 启用 CBO 优化 为了提升查询性能,启用基于成本的优化器(Cost-Based Optimizer, CBO)是一个重要手段。通过设置如下参数,可以让Hive利用统计信息来进行更有效的查询规划: ```sql set hive.cbo.enable=true; set hive.compute.query.using.stats=true; set hive.stats.fetch.column.stats=true; set hive.stats.fetch.partition.stats=true; ``` 这些配置使得Hive能够根据实际的数据分布情况做出更好的决策,比如选择最优的连接顺序和方式等[^1]。 #### 减少笛卡尔积的发生 避免不必要的全表扫描以及防止产生过多的小文件对于提高查询速度至关重要。当两个大表之间发生无条件关联时就会形成笛卡尔积,这会极大地增加计算复杂度并拖整个过程。因此,在编写SQL语句时应尽可能加入过滤条件以限制参与运算的数据范围。 #### 使用分桶技术 创建分桶表有助于加速某些类型的查询操作。例如,如果经常按`id`字段进行筛选,则可考虑将该字段设为分桶键。这样做不仅能使数据存储更加有序,而且还能让Hive引擎在读取过程中跳过不相关的分区,进而加快响应时间。 ```sql -- 创建分桶表 CREATE TABLE sales_bucketed ( id INT, date STRING, product STRING, amount DOUBLE ) CLUSTERED BY (id) INTO 4 BUCKETS; -- 加载数据到分桶表 INSERT INTO TABLE sales_bucketed SELECT id, date, product, amount FROM raw_sales; -- 查询分桶表数据 SELECT * FROM sales_bucketed WHERE id = 100; ``` 这种方法特别适用于那些频繁访问特定区间内的记录的应用场景[^3]。 #### 构建物化视图 物化视图是一种预先计算好结果集的对象,它可以在后续多次相同模式下的查询请求到来之前就准备好所需的结果集合。相比临时构建中间表的方式而言,这种方式能显著降低重复劳动所带来的开销。 ```sql -- 创建物化视图 create materialized view mater_view_dim_ad_info as select * from dim_ad_full_transaction; describe mater_view_dim_ad_info; SELECT * FROM mater_view_dim_ad_info; ``` 此特性非常适合于报表生成类的任务,因为这类任务通常具有固定的查询结构并且对实时性的要求相对较低[^4]。 除了上述措施外,还需要关注其他方面的影响因素,如合理调整Job数量、控制磁盘与网络I/O负载、优化MapReduce框架的相关参数设定等,这些都是保障高效运行不可或缺的部分[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值