使用Impala hint加速SQL查询

在使用Impala进行SQL查询的时候,我们经常会使用join来关联多个表进行查询,获取想要的结果。对于表的数量达到千万甚至上亿的时候,不同的join方式所造成的执行速度,可能差距非常大。对于join的实现细节,感兴趣的可以参考:http://hbasefly.com/2017/03/19/sparksql-basic-join/。想直接了解如何加速SQL查询的可以直接跳过这里了。

Impala提供了broadcast和shuffle两种join的方式,那么这两种方式有什么区别呢?可以简单这么理解:

  • Broadcast适合大表与小表的join,将大表划分成多块,小表广播与这些块进行hash join;
  • Shuffle适合大表与大表的join,将两个大表都划分成多块,然后分别进行hash join,有点类似于mapreduce中的shuffle。

Impala在查询的时候,会根据每个表的统计信息,自动地选择相应的join方式。可以使用以下的SQL语句来给表加上统计信息:

COMPUTE STATS [db_name.]table_name
COMPUTE INCREMENTAL STATS [db_name.]table_name [PARTITION (partition_spec)]

 

如果用户没有及时地给表进行了统计信息操作或者查询的是kudu表(目前impala无法获取到kudu表的统计信息),那么有可能生成的执行计划就会非常不准确,如下图所示:

上图就是使用了broadcast的join方式,将9000w的数据进行broadcast,与30亿的数据进行join。这样不仅执行比较慢,也会非常消耗内存。此时,我们就可以使用hint来改变SQL的join方式,impala的hint使用非常简单,如下所示:

SELECT STRAIGHT_JOIN select_list FROM
join_left_hand_table
  JOIN [{ /* +BROADCAST */ | /* +SHUFFLE */ }]
join_right_hand_table
remainder_of_query;

INSERT insert_clauses
  [{ /* +SHUFFLE */ | /* +NOSHUFFLE */ }]
  [/* +CLUSTERED */]
  SELECT remainder_of_query;

SELECT select_list FROM
table_ref
  /* +{SCHEDULE_CACHE_LOCAL | SCHEDULE_DISK_LOCAL | SCHEDULE_REMOTE}
    [,RANDOM_REPLICA] */
remainder_of_query;

以上是官方的语法介绍,看起来可能比较晦涩,我们举一个简单的例子进行说明:

select c_custkey,count(o_orderkey) 
from customer 
join orders
on c_custkey = o_custkey and o_comment not like '%[WORD1]%[WORD2]%'
group by c_custkey 
order by c_custkey limit 10;

上面这个SQL我们在测试环境中执行,部分执行计划如下所示:

可以看到,这里默认使用了broadcast的方式,那么如何改变使用shuffle的join方式呢,修改后的SQL如下所示:

select STRAIGHT_JOIN c_custkey,count(o_orderkey) 
from customer 
join [shuffle] orders
on c_custkey = o_custkey and o_comment not like '%[WORD1]%[WORD2]%'
group by c_custkey 
order by c_custkey limit 10;

可以看到,当我们在SQL的相应部分加入了STRAIGHT_JOIN和[shuffle]之后,SQL的执行计划就发生了改变。这里的[shuffle]也可以换成/* +shuffle */,意义是一样的,当然如果我们需要使用broadcast的方式,可以使用[broadcast]或者/* +broadcast */。请注意,有两个地方需要加上hint关键字,select后面加上STRAIGHT_JOIN;join后面加上[shuffle]或者/* +shuffle */。如果是多层嵌套的join方式,也需要在每一层加上STRAIGHT_JOIN和[shuffle]或者/* +shuffle */。外层的hint对于内层的join子语句是不起作用的。如果select后面跟distinct之类的关键字,STRAIGHT_JOIN需要跟在关键字后面。

除了可以改变join的方式之外,impala hint还支持一些其他的功能,这里就不再过多描述,感兴趣的同学可以参考官方文档:https://www.cloudera.com/documentation/enterprise/5-11-x/topics/impala_hints.html

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值