避免 Spark SQL 查询的笛卡尔连接
Posted
技术标签:
【中文标题】避免 Spark SQL 查询的笛卡尔连接【英文标题】:Avoid Cartesian Join for the spark SQL query 【发布时间】:2021-04-05 10:05:07 【问题描述】:我正在尝试根据两个临时表的总数计算 processRate,但我收到错误“检测到逻辑计划之间的 INNER 连接的隐式笛卡尔积”,我什至没有执行连接。我确信可以通过以正确格式重组查询来解决此错误,我需要您的帮助。下面是查询,
spark.sql("""
CREATE OR REPLACE TEMPORARY VIEW final_processRate AS
SELECT
((a.total - b.total)/a.total))* 100 AS processRate
FROM
(select count (*) as total from sales) a,
(select count (*) as total from sales where status = 'PENDING') b
""")
我在尝试使用查看数据时遇到此错误,
spark.sql("select * from processRate limit 10").show(false)
您能否帮助格式化上述查询以解决此问题并查看final_processRate
的数据?
【问题讨论】:
“我什至没有执行连接” - 为什么您认为这不是连接?我的意思是,你有FROM a,b
- 如果不是加入,还有什么?
另外,您可以为 Spark 启用交叉连接,尽管笛卡尔积通常应该很慢:***.com/a/39000050/4744359 - 对于 Spark 3,它将默认启用,因此您使用的是无论如何,旧版本的 Spark。为什么?
【参考方案1】:
您不需要子查询。只需使用条件聚合:
spark.sql("""
CREATE OR REPLACE TEMPORARY VIEW final_processRate AS
SELECT
((count(*) - count(case when status='PENDING' then 1 end)) / count(*)) * 100 AS processRate
FROM sales
""")
然后您可以使用以下命令查询临时视图:
spark.sql("select * from final_processRate")
它应该给你一个上面计算的数字/百分比。
【讨论】:
非常感谢!!有效!!你能解释一下这两个查询之间的区别吗?这对我理解更深层次的逻辑非常有帮助。 您的查询涉及 a 和 b 之间的隐式交叉联接,因为您在from
中有两个表,导致错误。【参考方案2】:
我会这样写:
select avg(case when status = 'PENDING' then 0.0 else 1 end)
from sales;
这将返回未挂起的行的比例。
【讨论】:
以上是关于避免 Spark SQL 查询的笛卡尔连接的主要内容,如果未能解决你的问题,请参考以下文章