SparkSQL 中的表连接顺序以获得更好的性能

Posted

技术标签:

【中文标题】SparkSQL 中的表连接顺序以获得更好的性能【英文标题】:Order of table joining in SparkSQL for better performance 【发布时间】:2020-06-20 17:47:12 【问题描述】:

我是 Spark-SQL 的新手,无法阅读 Hive 表格。我想知道 Spark 如何执行 多表 Join。我在某处读到,建议始终将 largest 表保留在 Join order 的顶部等等,这有利于Join 的效率。我在 Join 中读到,Spark 按顺序将第一个表(最大)加载到 Memory 并流式传输另一个表,这有助于提高 Join 性能。但是,我对这种策略如何提高性能感到困惑,因为最大的表(在大多数情况下)不适合内存并溢出到磁盘上。

任何人都可以在加入时澄清和解释 Spark 在幕后使用的加入机制 [large vs medium]、[large vs small] 和 [large vs large] 表在连接类型(inner & outer)和连接性能方面。我想知道在连接表排序方面应该遵循的最佳实践,以实现 Spark 采用的所有连接策略(SMJ、ShuffleHash 和广播)的最佳性能。让我们假设以下查询:

select 
a.id, 
b.cust_nm, 
c.prod_nm
from large_tab a
join medium_tab b
on a.id = b.id
join small_tab c
on a.pid = c.pid;

注意:我们使用 Spark 2.4

非常感谢任何帮助。谢谢。

【问题讨论】:

这可能是有用的描述 - github.com/apache/spark/blob/v2.4.0/sql/core/src/main/scala/org/… 【参考方案1】:

关于join的顺序,Spark提供了查找join中表的最优配置(顺序)的功能,但它与一些配置设置有关(下面的代码在PySpark API中提供):

    CBO - 必须开启基于成本的优化器(在 2.4 中默认关闭)
spark.conf.set("spark.sql.cbo.enabled", True)
    joinReorder 必须开启(在 2.4 中默认关闭)
spark.conf.set("spark.sql.cbo.joinReorder.enabled", True)
    为了让它尽可能地工作,最好先计算表的统计信息。这可以按如下方式完成:
spark.sql("ANALYZE TABLE table_name COMPUTE STATISTICS FRO COLUMNS col1, col2, ...")

在这里计算统计信息非常重要,因为 Spark 将基于此估计连接中表的大小并相应地重新排序它们。为了获得更好的估计,您还可以启用列的直方图计算(这在 2.4 中默认也是关闭的):

spark.conf.set("spark.sql.statistics.histogram.enabled", True)

这个joinReorder可以使用的表的最大数量可以通过这个设置来控制

spark.sql.cbo.joinReorder.dp.threshold

默认值为 12。

【讨论】:

你能解释一下鼓掌与赞成的概念吗? @thebluephantom 你所说的鼓掌和赞成的概念是什么意思? 好吧,更多的舌头在脸颊。我没有得到新的评级系统。姚似乎知道很多,所以我想我会随机问你。干杯 哦,我明白了,好吧,抱歉,我对评分系统了解不多。 你似乎是个聪明人,可以就我最近遇到的问题提供任何建议:***.com/questions/62511615/…

以上是关于SparkSQL 中的表连接顺序以获得更好的性能的主要内容,如果未能解决你的问题,请参考以下文章

Ram 或 DB 表中的表,以获得最佳性能

Django South:结合“alter table”以获得更好的性能?

Oracle 性能优化

Oracle 性能优化

SQL性能优化

SQL基础系列-性能优化建议