spark sql中的临时表怎么读取数据

spark sql中的临时表怎么读取数据,第1张

Spark SQL就是shark ,也就是SQL on Spark。如果没记错的话,shark的开发利用了hive的API,所以支持读取HBase。而且Spark的数据类型兼容范围大于Hadoop,并且包含了Hadoop所支持的任何数据类型。

Spark SQL主要的推动者是Databricks。提到Spark SQL不得不提的就是Shark。Shark可以理解为Spark社区这边搞的一个”Hive on Spark”,把Hive的物理执行计划使用Spark计算引擎去执行。这里面会有一些问题,Hive社区那边没有把物理执行计划到执行引擎这个步骤抽象出公共API,所以Spark社区这边要自己维护一个Hive的分支,而且Hive的设计和发展不太会考虑到如何优化Spark的Job。但是前面提到的Hive on Spark却是和Hive一起发布的,是由Hive社区控制的。所以后来Spark社区就停止了Shark的开发转向Spark SQL(“坑了”一部分当时信任Shark的人)。Spark SQL是把SQL解析成RDD的transformation和action,而且通过catalyst可以自由、灵活的选择最优执行方案。对数据库有深入研究的人就会知道,SQL执行计划的优化是一个非常重要的环节,Spark SQL在这方面的优势非常明显,提供了一个非常灵活、可扩展的架构。但是Spark SQL是基于内存的,元数据放在内存里面,不适合作为数据仓库的一部分来使用。所以有了Spark SQL的HiveContext,就是兼容Hive的Spark SQL。它支持HiveQL, Hive Metastore, Hive SerDes and Hive UDFs以及JDBC driver。这样看起来很完美,但是实际上也有一些缺点:Spark SQL依赖于Hive的一个snapshot,所以它总是比Hive的发布晚一个版本,很多Hive新的feature和bug fix它就无法包括。而且目前看Spark社区在Spark的thriftserver方面的投入不是很大,所以感觉它不是特别想朝着这个方向发展。还有一个重要的缺点就是Spark SQL目前还不能通过分析SQL来预测这个查询需要多少资源从而申请对应的资源,所以在共享集群上无法高效地分配资源和调度任务。

问题: 在调试一个sparksql左连接查询时发现数据结果不正确,经过一天折腾才发现使用子查询方式能够得到正确的结果,分析执行计划发现第一种写法的优化后的执行计划将where tip is null and tdn条件错误的加到了左表子查询中了,即红色标出的地方,这样导致左表子查询查不出数据来。

结论: 过滤条件写在where条件中时,spark会将sql优化为inner join, 如果连接条件中的字段出现在最后的where条件中,那么该条件在做谓词下推时也会被加到左表和右表中,此时就不符合预期结果,即会导致左表中的查不到预期的数据,但是将过滤数据用的限定条件写到子查询中时查出的结果是正确的,执行计划也是正确的,原因不详,怀疑是spark执行计划优化中的bug;

过程数据记录

1、条件在where中

select

onedaydn, onedayip, '20201202', '20201202'

from

(

select

ip,dn

from dwd_dnst_ip_dn_his_rel2

where dt = '20201202'

group by ip,dn

) oneday left join dwd_dnst_ip_dn_first t on tip = onedayip and tdn = onedaydn

where tip is null and tdn is null and tdt = '20201001'

执行计划:

== Optimized Logical Plan ==

InsertIntoHiveTable dwd_dns t_ip_dn_first , orgapachehadoophiveqlioorcOrcSerde, Map(dt -> None), true, false, [dn, ip, first_time, dt]

+- Project [dn#1, ip#2, 20201202 AS first_time#28, 20201202 AS dt#29]

+- Join Inner, ((ip#8 = ip#2) && (dn#7 = dn#1))

:- Aggregate [ip#2, dn#1], [ip#2, dn#1]

: +- Project [dn#1, ip#2]

: +- Filter (((((isnotnull(dt#6) && (dt#6 = 20201202)) && isnull(dn#1)) && isnull(ip#2)) && isnotnull(ip#2)) && isnotnull(dn#1))

: +- Relation[uid#0,dn#1,ip#2,cname#3,dnsip#4,probe_time#5,dt#6] orc

+- Project [dn#7, ip#8]

+- Filter (((((isnotnull(dt#10) && isnull(ip#8)) && isnull(dn#7)) && (dt#10 = 20201001)) && isnotnull(ip#8)) && isnotnull(dn#7))

+- Relation[dn#7,ip#8,first_time#9,dt#10] orc

2、条件在子查询中

select

/ + REPARTITION(10) /

onedaydn, onedayip, '20201202', '20201202'

from

(

select

ip,dn

from dwd_dnst_ip_dn_his_rel2

where dt = '20201202'

group by ip,dn

) oneday left join

(

select dn, ip

from

dwd_dnst_ip_dn_first

where dt = '20201001'

) t on tip = onedayip and tdn = onedaydn

where tip is null and tdn is null

执行计划:

== Optimized Logical Plan ==

InsertIntoHiveTable dwd_dns t_ip_dn_first , orgapachehadoophiveqlioorcOrcSerde, Map(dt -> None), true, false, [dn, ip, first_time, dt]

+- Project [dn#1, ip#2, 20201202 AS first_time#28, 20201202 AS dt#29]

+- Repartition 10, true

+- Project [dn#1, ip#2]

+- Filter (isnull(ip#8) && isnull(dn#7))

+- Join LeftOuter, ((ip#8 = ip#2) && (dn#7 = dn#1))

:- Aggregate [ip#2, dn#1], [ip#2, dn#1]

: +- Project [dn#1, ip#2]

: +- Filter (isnotnull(dt#6) && (dt#6 = 20201202))

: +- Relation[uid#0,dn#1,ip#2,cname#3,dnsip#4,probe_time#5,dt#6] orc

+- Project [dn#7, ip#8]

+- Filter (((isnotnull(dt#10) && (dt#10 = 20201001)) && isnotnull(ip#8)) && isnotnull(dn#7))

+- Relation[dn#7,ip#8,first_time#9,dt#10] orc

以上就是关于spark sql中的临时表怎么读取数据全部的内容,包括:spark sql中的临时表怎么读取数据、如何使用Spark SQL 的JDBC server、一次sparksql问题排查记录等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10631565.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-10
下一篇2023-05-10

发表评论

登录后才能评论

评论列表(0条)

    保存