我正在使用 Spark sql 对 parquet 数据源运行一些聚合查询。
我的 parquet 数据源包括一个表,其中包含以下列:id int、时间时间戳、位置 int、counter_1 long、counter_2 long、...、counter_48。总数据大小约为887 MB。
我的spark版本是2.4.0。我在一台机器上运行一主一从(4核,16G内存)。
使用 Spark-shell,我运行了 Spark 命令:
spark.time(spark.sql("SELECT location, sum(counter_1)+sum(counter_5)+sum(counter_10)+sum(counter_15)+sum(cou
nter_20)+sum(counter_25)+sum(counter_30)+sum(counter_35 )+sum(counter_40)+sum(counter_45) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())
执行时间为17s。
我第二次运行类似的命令(仅更改列):
spark.time(spark.sql("SELECT location, sum(counter_2)+sum(counter_6)+sum(counter_11)+sum(counter_16)+sum(cou
nter_21)+sum(counter_26)+sum(counter_31)+sum(counter_36 )+sum(counter_41)+sum(counter_46) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())
执行时间约为3s。
我的第一个问题是:为什么它们不同?我知道这不是数据缓存,因为镶木地板格式。是关于重用查询计划之类的东西吗?
我做了另一个测试:第一个命令是
spark.time(spark.sql("SELECT location, sum(counter_1)+sum(counter_5)+sum(counter_10)+sum(counter_15)+sum(cou
nter_20)+sum(counter_25)+sum(counter_30)+sum(counter_35 )+sum(counter_40)+sum(counter_45) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())
执行时间为17s。
在第二个命令中,我更改了聚合函数:
spark.time(spark.sql("SELECT location, avg(counter_1)+avg(counter_5)+avg(counter_10)+avg(counter_15)+avg(cou
nter_20)+avg(counter_25)+avg(counter_30)+avg(counter_35 )+avg(counter_40)+avg(counter_45) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())
执行时间约为5s。
我的第二个问题是:为什么第二个命令比第一个命令快,但执行时间差异却比第一个场景略小?
最后,我有一个与上述场景相关的问题:大约有 200 个公式,例如:
formula1 = sum(counter_1)+sum(counter_5)+sum(counter_10)+sum(counter_15)+sum(cou
nter_20)+sum(counter_25)+sum(counter_30)+sum(counter_35 )+sum(counter_40)+sum(counter_45)
formula2 = avg(counter_2)+avg(counter_5)+avg(counter_11)+avg(counter_15)+avg(cou
nter_21)+avg(counter_25)+avg(counter_31)+avg(counter_35 )+avg(counter_41)+avg(counter_45)
我必须经常运行以下格式:
select formulaX,formulaY, ..., formulaZ from table where time > value1 and time < value2 and location in (value1, value 2...) group by location
我的第三个问题是:有没有办法优化性能(使用过一次的查询如果将来再次使用应该会更快)? Spark 会自我优化还是我必须编写一些代码,更改配置?