火花内联与。横向视图分解差异?

Spark INLINE Vs. LATERAL VIEW EXPLODE differences?

在 Spark 中,对于以下用例,我想了解使用 INLINE and EXPLODE 之间的主要区别是什么......我不确定是否有任何性能影响,或者是否有一个方法优于另一种方法,或者如果存在任何其他用例,其中一种适用而另一种不适用...

用例是 select 来自复杂数据类型(结构数组)的 2 个字段,我的直觉是使用 INLINE,因为它 分解了一个结构数组

例如:

WITH sample AS (
 SELECT 1 AS id,
        array(NAMED_STRUCT('name', 'frank',
                           'age', 40,
                           'state', 'Texas'
                           ),
              NAMED_STRUCT('name', 'maria',
                           'age', 51,
                           'state', 'Georgia'
                           )
              )            
            AS array_of_structs
),

inline_data AS (
SELECT id,
        INLINE(array_of_structs)
FROM sample
)

SELECT id,
        name AS person_name,
        age AS person_age
FROM inline_data

并使用 LATERAL VIEW EXPLODE:

WITH sample AS (
 SELECT 1 AS id,
        array(NAMED_STRUCT('name', 'frank',
                           'age', 40,
                           'state', 'Texas'
                           ),
              NAMED_STRUCT('name', 'maria',
                           'age', 51,
                           'state', 'Georgia'
                           )
              )            
            AS array_of_structs
)

SELECT  id,
        person.name,
        person.age
FROM sample
LATERAL VIEW EXPLODE(array_of_structs) exploded_people as person 

文档清楚地说明了每一个的作用,但我想更好地理解何时选择一个而不是另一个。

EXPLODE UDTF 将生成结构行(结构类型的单列),要获取人名,您需要使用 person.name:

WITH sample AS (
 SELECT 1 AS id,
        array(NAMED_STRUCT('name', 'frank',
                           'age', 40,
                           'state', 'Texas'
                           ),
              NAMED_STRUCT('name', 'maria',
                           'age', 51,
                           'state', 'Georgia'
                           )
              )            
            AS array_of_structs
)

SELECT  id,
        person.name,
        person.age
FROM sample
LATERAL VIEW explode(array_of_structs) exploded_people as person

结果:

id,name,age
1,frank,40
1,maria,51

INLINE UDTF 将生成一个包含 N 列的行集(N = 结构中顶级元素的数量),因此您不需要使用点符号 person.name 因为 name 和其他结构元素已被 INLINE:

提取
WITH sample AS (
 SELECT 1 AS id,
        array(NAMED_STRUCT('name', 'frank',
                           'age', 40,
                           'state', 'Texas'
                           ),
              NAMED_STRUCT('name', 'maria',
                           'age', 51,
                           'state', 'Georgia'
                           )
              )            
            AS array_of_structs
)

SELECT  id,
        name,
        age
FROM sample
LATERAL VIEW inline(array_of_structs) exploded_people as name, age, state

结果:

id,name,age
1,frank,40
1,maria,51 

INLINEEXPLODE 都是 UDTF,在 Hive 中需要 LATERAL VIEW。在 Spark 中,它在没有侧视图的情况下工作正常。唯一的区别是 EXPLODE returns 数组元素数据集(在您的情况下为结构)和 INLINE 用于获取已提取的结构元素。在 INLINE 的情况下,您需要定义所有结构元素,如下所示:LATERAL VIEW inline(array_of_structs) exploded_people as name, age, state

从性能角度来看,INLINE 和 EXPLODE 的工作原理相同,您可以使用 EXPLAIN 命令来检查计划。在 UDTF 中或 UDTF 之后提取结构元素不会影响性能。

INLINE需要描述所有的struct元素(在Hive中)而EXPLODE不需要,所以如果你不需要提取所有的struct元素或者根本不需要提取元素,explode可能更方便。当您需要提取全部或大部分结构元素时,INLINE 很方便。

您的第一个代码示例仅适用于 Spark。在 Hive 2.1.1 中,它抛出异常,因为需要 lateral view

在 Spark 中这也适用:

inline_data AS (
SELECT id,
        EXPLODE(array_of_structs) as person
FROM sample
)

要获取年龄列,您需要使用 person.age