大数据

hive 开启vectorized中的坑

文 / sptk 来源 / 原创 阅读 / 31 4周前

hive中有一个优化是, 默认hive处理数据按行处理,开启后会按批处理,加快我们的执行效率. 官方文档: https://cwiki.apache.org/confluence/display/Hive/Vectorized+Query+Execution 开启参数如下: SET hive.vectorized.execution.enabled = true; # 关键优化参数,一般是指的map端开启的矢量化 SET hive.vectorized.execution.reduce.enabled = true; # 注意这个优化一般是计算引擎为tez 或者 spark的时候才会生效

#  插入测试数据
drop table  if exists user_sessions;
CREATE TABLE user_sessions (
  user_id INT,
  login_ts TIMESTAMP,  -- 登录时间
  logout_ts TIMESTAMP  -- 登出时间
) STORED AS orc;

INSERT INTO TABLE user_sessions VALUES
  (101, '2023-09-21 08:00:00', '2023-09-21 08:30:00'),
  (102, '2023-09-21 09:00:00', '2023-09-21 09:30:00'),
  (103, '2023-09-21 09:10:00', '2023-09-21 10:30:00');

#  需求:  查询用户的的在线时间,并按照在线时间排序?

# 开启矢量化优化
SET hive.vectorized.execution.enabled = true;

#  可以通过下面的查询执行计划, 发现已开启矢量化
explain VECTORIZATION select
    user_id,
    unix_timestamp(logout_ts),
    unix_timestamp(login_ts),
    unix_timestamp(logout_ts) - unix_timestamp(login_ts) sjc
from user_sessions
order by login_ts, logout_ts;

#  执行查询
select
    user_id,
    unix_timestamp(logout_ts),
    unix_timestamp(login_ts),
    unix_timestamp(logout_ts) - unix_timestamp(login_ts) sjc
from user_sessions
order by login_ts, logout_ts;

上面的查询结果正常, 没有任何问题. 注意解解下来我们对上面的计算做一个处理 cast((unix_timestamp(logout_ts) - unix_timestamp(login_ts)) as int) sjc

#  调整后查询, 注意这个仍然是在开启矢量化下面进行
select
    user_id,
    unix_timestamp(logout_ts),
    unix_timestamp(login_ts),
    cast((unix_timestamp(logout_ts) - unix_timestamp(login_ts))  as int) sjc
from user_sessions
order by login_ts,logout_ts;

经过上面的查询, 你会惊奇的发现 sjc 计算结果全部为0. 而我们查询仅仅是对类型做了一个cast转换, unix_timestamp是一个bigint类型 相当于做了一个bigint->int的转换,这个是一个向下转换,转换过程本身可能出现数据丢失.

#  在上面的基础上
#  关闭矢量化优化
SET hive.vectorized.execution.enabled = false;
select
    user_id,
    unix_timestamp(logout_ts),
    unix_timestamp(login_ts),
    cast((unix_timestamp(logout_ts) - unix_timestamp(login_ts))  as int) sjc
from user_sessions
order by login_ts,logout_ts;

当我们关闭矢量化计算的时候, 你会发现,计算结果一切正常, 可以正确的计算出结果, 下面我们进一步测试

#  开启矢量化
SET hive.vectorized.execution.enabled = true;

select
    user_id,
    unix_timestamp(logout_ts),
    unix_timestamp(login_ts),
    cast(current_timestamp() as int),   -- 对常量数据做转换
    cast(unix_timestamp(login_ts) as int),  -- 对矢量化数据做转换
    cast((unix_timestamp(logout_ts) - unix_timestamp(login_ts))  as int) sjc
from user_sessions
 order by login_ts,logout_ts;

上面的计算,你会发现, 开启矢量化的情况下面, 对常量数据做转换是可以正常的. 涉及到对矢量化的数据计算就差出现错误 根据上面的测试, 推测,cast 在矢量化计算上面,可能存在bug [hive2 hive3都做过测试] 所以请大家在矢量化计算过程, 使用cast的时候注意下,尤其是向下转换的时候.

1

站点声明:站点主要用于个人技术文章。

冀ICP备19037883号
相关侵权、举报、投诉及建议等,请发E-mail:804330969@qq.com