Hive:哪里+ in不使用分区?

cer*_*axt 8 hive partitioning

我正在查询一个被称为字段的大表day.如果我运行查询:

select * from my_table where day in ('2016-04-01', '2016-03-01')

我得到许多映射器和缩减器,查询需要很长时间才能运行.

但是,如果我写了一个查询:

select * from my_table where day = '2016-04-01' or day = '2016-03-01'

我的映射器和缩减器要少得多,查询运行得很快.对我来说,这表明in不利用表中的分区.谁能证实这一点并解释原因?

Hive版本:1.2.1
Hadoop版本:2.3.4.7-4

详细信息:
我相信,在执行计划的相关部分...
使用Where or
在无过滤器操作所有

使用Where in
Filter Operator predicate: (day) IN ('2016-04-01', '2016-03-01') (type: boolean) Statistics: Num rows: 100000000 Data size: 9999999999

hive文档只是说:
'查询中使用的分区是由系统根据分区列上的where子句条件自动确定的.

但是不要详细说明.我找不到与此直接相关的任何SO帖子.

谢谢!

小智 1

太长了;博士

我将Hive 1.1.0Cloudera 5.13.3结合使用,并根据我在 Hue 中运行的解释计划遵循IN与等于运算符 ( ) 相同的优化。=


例子

LOAD_YEAR (SMALLINT)我的表在和上进行分区,LOAD_MONTH (TINYINT)并且有这两个分区:

  1. load_year=2018/load_month=10(19,828,71 行)
  2. load_year=2018/load_month=11(702,856 行)

以下是各种查询及其解释计划。

1. 等号( =)运算符

询问:

SELECT ID
FROM TBL
WHERE LOAD_MONTH = 11Y
Run Code Online (Sandbox Code Playgroud)

解释计划:

STAGE DEPENDENCIES:
  Stage-0 is a root stage

STAGE PLANS:
  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        TableScan
          alias: tbl
          filterExpr: (load_month = 11) (type: boolean)
          Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
          Select Operator
            expressions: id (type: string)
            outputColumnNames: _col0
            Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
            ListSink
Run Code Online (Sandbox Code Playgroud)

2.IN操作员

查询(注意数据中没有12月份):

SELECT ID
FROM TBL
WHERE LOAD_MONTH IN (11Y, 12Y)
Run Code Online (Sandbox Code Playgroud)

解释计划:

STAGE DEPENDENCIES:
  Stage-0 is a root stage

STAGE PLANS:
  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        TableScan
          alias: tbl
          filterExpr: (load_month = 11) (type: boolean)
          Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
          Select Operator
            expressions: id (type: string)
            outputColumnNames: _col0
            Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
            ListSink
Run Code Online (Sandbox Code Playgroud)

3. 等于 ( =) 与 AND 和 OR 结合

询问:

SELECT ID
FROM TBL
WHERE
    (LOAD_YEAR = 2018S AND LOAD_MONTH = 11Y)
OR  (LOAD_YEAR = 2019S AND LOAD_MONTH = 1Y)
Run Code Online (Sandbox Code Playgroud)

解释计划:

STAGE DEPENDENCIES:
  Stage-0 is a root stage

STAGE PLANS:
  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        TableScan
          alias: tbl
          filterExpr: (((load_year = 2018) and (load_month = 11)) or ((load_year = 2019) and (load_month = 1))) (type: boolean)
          Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
          Select Operator
            expressions: id (type: string)
            outputColumnNames: _col0
            Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
            ListSink
Run Code Online (Sandbox Code Playgroud)

4.算术运算

询问:

SELECT ID
FROM TBL
WHERE (LOAD_YEAR * 100 + LOAD_MONTH) IN (201811, 201901)
Run Code Online (Sandbox Code Playgroud)

边注:

100 没有后缀,所以它是INT,(LOAD_YEAR * 100 + LOAD_MONTH)也是INT. 这确保了结果的准确性。由于LOAD_YEAR是 aSMALLINTLOAD_MONTHa TINYINT,所以对两者进行算术计算得出SMALLINT结果,并且存储的最大值是 32,767(对于 来说不够yyyymm,它需要 6 位数字,即至少最多 999,999)。以 100 作为INT,使用INT类型进行计算,允许的数字最大为 2,147,483,647。

解释计划:

STAGE DEPENDENCIES:
  Stage-0 is a root stage

STAGE PLANS:
  Stage: Stage-0
    Fetch Operator
      limit: -1
      Processor Tree:
        TableScan
          alias: tbl
          filterExpr: (201811) IN (201811, 201901) (type: boolean)
          Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
          Select Operator
            expressions: id (type: string)
            outputColumnNames: _col0
            Statistics: Num rows: 702856 Data size: 84342720 Basic stats: COMPLETE Column stats: NONE
            ListSink
Run Code Online (Sandbox Code Playgroud)

概括

所有这些查询仅扫描第二个分区,从而避免了另一个分区中的约 2000 万行。