谓词下推(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文件存储格局