Spark在 1.5.2 和 1.6.0 版本中创建不同的SQL执行计划。
数据库包含一个大型事实表( f )和几个小维度表( d1,d2 )。
维度表( d1,d2 )使用以下方式缓存在Spark中:
sqlContext.cacheTable("d1");
sqlContext.sql("SELECT * from d1").count();
sqlContext.cacheTable("d2");
sqlContext.sql("SELECT * from d2").count();
表 d1 和 d2 的大小: ~100MB (选项卡 STORAGE 显示此大小 Spark Web UI 中的表格。
Spark SQL由广播参数(1GB)配置,该参数大于表的大小:
spark.sql.autoBroadcastJoinThreshold=1048576000
SQL是:
SELECT d1.name, d2.name, SUM(f.clicks)
FROM f
JOIN d1 on f.d1_id = d1.id
JOIN d2 on f.d2_id = d2.id
WHERE d1.name='A' AND f.date=20160101
GROUP BY d1.name, d2.name
ORDER BY SUM(f.clicks) DESC
使用 ThriftServer 执行查询。
当我们使用Spark 1.5.2 运行此查询时,查询会快速执行,执行计划包含 BroadcastJoin 维度。
但是当我们使用Spark 1.6.0 运行相同的查询时,查询执行速度非常慢,执行计划包含带有维度的 SortMergeJoin
两次执行的环境相同(相同的 Yarn Cluster )。 提供的执行程序计数,每个执行程序的任务计数和执行程序的内存对于两个执行都是相同的。
在sql执行中如何配置Spark 1.6.0以使用BroadcastJoin?
感谢。