我的问题:为什么Spark会从每个分区计算sum
和count
,执行不必要的(IMHO)shuffle(Exchange hashpartitioning
),然后计算HashAggregate
中的平均值?
可以做什么:计算每个分区的平均值,然后合并(合并)结果。
详细信息:
我正在从下面定义的Hive表中读取数据,该表按日期分区。
spark.sql("""Create External Table If Not Exists daily_temp.daily_temp_2014
(
state_name string,
...
) Partitioned By (
date_local string
)
Location "./daily_temp/"
Stored As ORC""")
它包括从EPA Website下载的美国各点温度的每日测量值。
使用下面的代码,数据从Hive表加载到PySpark DataFrame:
spark = (
SparkSession.builder
.master("local")
.appName("Hive Partition Test")
.enableHiveSupport()
.config("hive.exec.dynamic.partition", "true")
.config("hive.exec.dynamic.partition.mode", "nonstrict")
.getOrCreate()
)
my_df = spark.sql("select * from daily_temp.daily_temp_2014")
我想计算每个州的日平均温度。
daily_state_mean = (
my_df
.groupBy(
my_df.date_local,
my_df.state_name
)
.agg({"arithmetic_mean":"mean"})
)
这是物理(执行)计划的一部分:
+- *(2) HashAggregate(keys=[date_local#3003, state_name#2998], functions=[avg(cast(arithmetic_mean#2990 as double))], output=[date_local#3003, state_name#2998, avg(CAST(arithmetic_mean AS DOUBLE))#3014])
+- Exchange hashpartitioning(date_local#3003, state_name#2998, 365)
+- *(1) HashAggregate(keys=[date_local#3003, state_name#2998], functions=[partial_avg(cast(arithmetic_mean#2990 as double))], output=[date_local#3003, state_name#2998, sum#3021, count#3022L])
+- HiveTableScan [arithmetic_mean#2990, state_name#2998, date_local#3003], HiveTableRelation `daily_temp`.`daily_temp_2014`, org.apache.hadoop.hive.ql.io.orc.OrcSerde, [...], [date_local#3003]
非常感谢您的建议和见解。
答案 0 :(得分:0)
这里没有任何意外。 Spark SQL不保留外部源的分区信息(<)。
如果您想优化随机播放,则可以使用CLUSTER BY
/ bucketBy
数据。如果这样做,分区信息将用于优化随机播放。