Introduction

向量化查询执行是 Hive 的一项功能,可大大减少典型查询操作(如扫描,过滤器,聚合和联接)的 CPU 使用率。标准查询执行系统一次处理一行。这在执行的内部循环中涉及长代码路径和重要的元数据解释。向量化查询执行通过一次处理一个 1024 行的块来简化操作。在该块内,每一列都存储为向量(原始数据类型的数组)。诸如算术和比较之类的简单操作是通过在一个紧密的循环中快速迭代向量而完成的,循环内没有或只有很少的函数调用或条件分支。通过有效地使用处理器管道和高速缓存,这些循环以精简的方式进行编译,该方式使用相对较少的指令,并平均在较少的时钟周期内完成每条指令。详细的设计文档位于https://issues.apache.org/jira/browse/HIVE-4160的矢量化查询执行 JIRA 上。

使用向量化查询执行

启用向量化执行

要使用向量化查询执行,必须以ORC格式存储数据,并设置以下变量,如 Hive SQL 中所示(请参见Configuring Hive):

set hive.vectorized.execution.enabled = true;

默认情况下,矢量化执行是关闭的,因此您的查询仅在启用此变量的情况下才使用它。要禁用向量化执行并返回标准执行,请执行以下操作:

set hive.vectorized.execution.enabled = false;

用于矢量化执行的其他配置变量记录在配置属性–矢量化中。

支持的数据类型和操作

向量化执行目前支持以下数据类型:

  • tinyint

  • smallint

  • int

  • bigint

  • boolean

  • float

  • double

  • decimal

  • date

  • timestamp(请参见下面的Limitations)

  • string

使用其他数据类型将导致您的查询使用标准的,一次一行的执行来执行。

在支持的类型上使用以下表达式时,可以对其进行向量化:

  • 算术:,-,*,/,%

  • 与,或,非

  • 比较\ <, >,\ <=, > =,=,!=,BETWEEN,IN(常量列表)作为过滤器

  • 使用 AND,OR,NOT,\ <, >,\ <=, > =,=,!=的布尔值表达式(非过滤器)

  • IS [NOT] NULL

  • 所有 math 函数(SIN,LOG 等)

  • 字符串函数 SUBSTR,CONCAT,TRIM,LTRIM,RTRIM,LOWER,UPPER,LENGTH

  • type casts

  • Hive 用户定义的功能,包括标准和通用 UDF

  • 日期函数(YEAR,MONTH,DAY,HOUR,MINUTE,SECOND,UNIX_TIMESTAMP)

  • IF 条件表达式

使用向后兼容 bridge 来支持用户定义的函数,因此尽管它们确实运行矢量化,但运行速度不如内置运算符和函数的优化矢量实现快。向量化的过滤器运算从左到右进行评估,因此为了获得最佳性能,请将 UDF 放在 WHERE 子句中 AND 表达式列表中的右边。例如使用

column1 = 10 and myUDF(column2) = "x"

instead of

myUDF(column2) = "x" and column1 = 10

这将允许优化的过滤器首先运行,从而有可能在通过网 bridge 运行 UDF 之前消除许多行。仅对在 AND 操作左侧通过过滤器的行运行 UDF。

使用不支持矢量化的内置运算符或函数将使您的查询以标准的一次行模式运行。如果出现与矢量化有关的编译时或运行时错误,请提交Hive JIRA。要变通解决此错误,请通过将失败的特定查询的hive.vectorized.execution.enabled设置为false来禁用向量化,以标准模式运行它。

continue 为其他功能和表达式添加了向量化支持。如果您要求一个,请在此页面上发表 Comment,或为此打开 JIRA。

查看是否对查询使用矢量化

您可以使用 explain 功能来验证查询的哪些部分已被矢量化。例如,当在计划中使用 Fetch 而不是 Map 时,它不会进行矢量化,并且说明输出将不包含“ Vectorized execution: true”表示法:

create table vectorizedtable(state string,id int) stored as orc;

insert into vectorizedtable values('haryana',1);
set hive.vectorized.execution.enabled = true;
explain select count(*) from vectorizedtable;

说明 输出包含以下内容:

STAGE PLANS:
  Stage: Stage-1
    Map Reduce
      Alias -> Map Operator Tree:
        alltypesorc
          TableScan
            alias: vectorizedtable
             Statistics: Num rows: 1 Data size: 95 Basic stats: COMPLETE Column stats: COMPLETE
            Select Operator
              Statistics: Num rows: 1 Data size: 95 Basic stats: COMPLETE Column stats: COMPLETE
              Group By Operator
                aggregations: count()
                mode: hash
                outputColumnNames: _col0
                Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
                Reduce Output Operator
                  sort order: 
                  Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
                  value expressions: _col0 (type: bigint)
      Execution mode: vectorized
      Reduce Operator Tree:
        Group By Operator
          aggregations: count(VALUE._col0)
          mode: mergepartial
          outputColumnNames: _col0
          Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
          File Output Operator
            compressed: false
            Statistics: Num rows: 1 Data size: 8 Basic stats: COMPLETE Column stats: COMPLETE
            table:
                input format: org.apache.hadoop.mapred.TextInputFormat
                output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat
                serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        ListSink

符号Vectorized execution: true表示包含该符号的运算符是矢量化的。缺少此表示法意味着不会对操作员进行矢量化处理,而是使用标准的一次性行执行路径。

注意 :如果您想使用向量化执行进行提取,则

set hive.fetch.task.conversion=none

Limitations

  • 如果时间戳值介于 1677-09-20 和 2262-04-11 之间,则时间戳只能与矢量化执行一起正常使用。此限制是由于以下事实:矢量化时间戳记值存储为长值,表示 1970 年 1 月 1 日 UTC 的 Unix 纪元时间之前/之后的纳秒。另请参见HIVE-9862

Version Information

Hive 0.13.0 和更高版本(HIVE-5283)中提供了向量化执行。