Hive:where + in 不使用分区?

Posted

技术标签:

【中文标题】Hive:where + in 不使用分区?【英文标题】:Hive: where + in does not use partition? 【发布时间】:2016-04-27 16:59:23 【问题描述】:

我正在查询一个在名为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

The hive docs 只是说: '在查询中使用哪些分区由系统根据分区列上的 where 子句条件自动确定。'

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

谢谢!

【问题讨论】:

between操作符一样 Hive 1.2.0 中存在此问题 【参考方案1】:

tl;博士

根据说明,我正在使用 Hive 1.1.0Cloudera 5.13.3IN 遵循与等号运算符 (=) 相同的优化我在顺化运行的计划。


示例

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

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

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

1.等号 (=) 运算符

查询:

SELECT ID
FROM TBL
WHERE LOAD_MONTH = 11Y

解释计划:

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

2。 IN运营商

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

SELECT ID
FROM TBL
WHERE LOAD_MONTH IN (11Y, 12Y)

解释计划:

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

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

查询:

SELECT ID
FROM TBL
WHERE
    (LOAD_YEAR = 2018S AND LOAD_MONTH = 11Y)
OR  (LOAD_YEAR = 2019S AND LOAD_MONTH = 1Y)

解释计划:

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

4.算术运算

查询:

SELECT ID
FROM TBL
WHERE (LOAD_YEAR * 100 + LOAD_MONTH) IN (201811, 201901)

旁注:

100 没有后缀,所以它是一个INT,而(LOAD_YEAR * 100 + LOAD_MONTH) 也是一个INT。这确保了结果是准确的。由于LOAD_YEARSMALLINTLOAD_MONTHTINYINT,因此对两者的算术计算使用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

总结

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

【讨论】:

以上是关于Hive:where + in 不使用分区?的主要内容,如果未能解决你的问题,请参考以下文章

hive的严格模式和分区

Hive - 分区查询不返回任何内容

Hive - 仅获取一个或多个 hive 表的最新分区

Hive 分区验证

大数据技术之Hive查询分区表和分桶表

大数据技术之Hive查询分区表和分桶表