我们是否应该在 SparkSQL 中的连接查询中为每个表创建单独的数据帧



我们需要在Spark SQL中转换和执行执行hive查询。查询涉及 2 个表之间的联接。我们将创建一个数据帧,然后在它之上创建 Sparksql 查询。请查找示例配置单元查询以及转换后的查询。

------配置单元查询

select a.col1,a.col2,a.col3,b.col4,b.col5,b.col6.b.col7
from table1 a left outer join table2 b
on a.col3=b.col3

-----Spark SQL

import org.apache.spark.sql.hive.HiveContext
val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
val q1=hivecontext.sql("select col1,col2,col3,col4 from table1");
val q2=hivecontext.sql("select col3,col5,col6,col7 from table2");
val q3=q1.join(q2,q1("col3")===q2("col3"));

但是我们也可以在单个数据框中执行整个查询,如下所示

**

val q5=hivecontext.sql("select 
a.col1,a.col2,a.col3,b.col4,b.col5,b.col6.b.col7
from table1 a left outer join table2 b
on a.col3=b.col3")**

我想知道在这种情况下我们更好地使用两种方法(单数据帧与多数据帧(中的哪一种,以及在性能和可读性等各种参数上优于另一种方法的优势。

第二种方法似乎在各个方面都是明智的

  1. 在 Hive 数据上运行 SQL 时,HiveContext 将在 Hive 中运行查询,并将结果元数据返回到 Spark。所以 Spark 只需要存储生成的元数据集。但在上述情况下,它必须将蜂巢中的所有数据存储到其RDD中。
  2. 维护单个RDD也有助于优化DAG。
  3. 如果你作为单个查询运行,即使是Spark catalyst也会进一步优化它。
  4. 它的可读性看起来更好。

这两种方法是相同的。从性能的角度来看,这并不重要。催化剂优化器将为这两个查询创建相同的物理计划。

但是,现在还有其他方面需要考虑。编写 SQL 查询通常很容易,但是您丢失了编译时类型检查。如果 SQL 中有拼写错误或列名不正确,则除非在群集上运行该列名,否则无法找到。但是,如果使用数据帧操作,则代码不会编译。因此,它有助于提高编码速度。

但是,使用数据帧 API 编写复杂的 SQL 也不是一件容易的事。因此,通常我使用操作相对简单的数据帧API,并使用SQL进行复杂查询。

相关内容

最新更新