乐趣区

关于hive:利用好谓词下推提升Hive性能

谓词下推(Predicate Pushdown,简称 PPD),是指尽量将 SQL 查问中的谓词(where 条件)提前执行,缩小后续操作的数量和计算量。在 Hive 中默认是开启的,也能够通过配置 SET hive.optimize.ppd=true; 显式开启。例如,对于如下 SQL

select a.*, b.* 
from a join b on (a.col1 = b.col1)
where a.col1 > 20 and b.col2 > 40

如果开启了谓词下推,在 join 之前会先执行 where 语句中对两个表的过滤操作,从而缩小读取和计算的数据量。否则,会先 join 再过滤。

除了 SQL 语句执行层面,在文件存储层面(ORC、Parquet 等格局),也会有谓词下推的思维。

以 ORC 为例,每个 ORC 文件保留了三个层级的索引:

  • file level:蕴含整个文件每列的统计信息
  • stripe level:每个 stripe 内每列的统计信息
  • row level:在同一个 stripe 内每 10000 行进行统计,失去每列的统计信息

file 和 stripe 级别的统计信息保留在 file footer 中,能够疾速过滤 where 条件中不须要读取的文件。row 级别索引蕴含了每个 row group 的列统计信息和 row group 的起始地位。

列统计信息根本都会蕴含其取值数量、是否蕴含 null,大部分根本类型的列还会蕴含最小值(min)、最大值(max),数值型的列还有总和(sum)。所有层级的索引都能够用于对须要读取的数据进行过滤。例如,有一个查问语句心愿获取年龄大于 100 岁的记录,where 条件中的语句应该为 age > 100,那么执行时只会读取蕴含年龄大于 100 岁的文件、stripe 或 row groups。

但要留神有些操作会使文件存储层面的谓词下推生效,在写代码的时候须要留神。例如,有个日志工夫字段 log_time,其存储的数据格式为 2023-01-01 10:00:00,当初须要取某一天的数据,可能会利用 to_date 函数:

select
    * 
from table_a 
where to_date(log_time) = '2023-01-09';

但下面的语句就无奈利用 ORC 文件索引来疾速过滤不须要的文件、stripe 或 row group,因为对字段 log_time 调用了函数 to_date,导致在真正开始运算前无奈晓得 to_date(log_time) 的理论值。如果批改为应用如下写法,则能够利用文件层面的疾速过滤:

select
    * 
from table_a 
where log_time >= '2023-01-09';
    and log_time < '2023-01-10';

另外,下面咱们提到文件、strip、row group 的统计信息会存储相应数据中是否蕴含 null,因而倡议应用 null 而不是 ”-“、”” 等来示意空逻辑。

对以上内容做个小结,利用好谓词下推来晋升 Hive 性能,咱们能够:

  • 先过滤再 join。Hive 中默认开启,无需特地关注
  • 在 where 语句中,尽量不要应用函数,例如 to_date
  • 应用 null 而不是 ”-“、”” 等来示意空逻辑

参考资料:

Apache ORC 文档:Indexes
Hive Optimization — Quick Refresher
什么是谓词下推,看这一篇就够了
大数据:Hive-ORC 文件存储格局

退出移动版