You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The performance issue seems specific to the first_value aggregate function. The dropDuplicates call is equivalent to:
select ss_item_sk, ss_quantity, first_value(ss_sold_date_sk), first_value(ss_sold_time_sk), first_value(ss_customer_sk), first_value(ss_cdemo_sk), first_value(ss_hdemo_sk), first_value(ss_addr_sk), first_value(ss_store_sk), first_value(ss_promo_sk), first_value(ss_ticket_number), first_value(ss_wholesale_cost), first_value(ss_list_price), first_value(ss_sales_price), first_value(ss_ext_discount_amt), first_value(ss_ext_sales_price), first_value(ss_ext_wholesale_cost), first_value(ss_ext_list_price), first_value(ss_ext_tax), first_value(ss_coupon_amt), first_value(ss_net_paid), first_value(ss_net_paid_inc_tax), first_value(ss_net_profit) from store_sales group by ss_item_sk, ss_quantity
Using min instead of first_value is much faster.
Here is how I tested:
defbench(aggr: String) {
valdf= spark.read.parquet("/mnt/bigdata/tpcds/sf100/store_sales.parquet")
valcols= df.schema.fieldNames.filterNot(name =>Seq("ss_item_sk", "ss_quantity").contains(name))
df.repartition($"ss_item_sk").createOrReplaceTempView("store_sales")
valsql=s"select ss_item_sk, ss_quantity, ${cols.map(name =>s"$aggr($name)").mkString(", ")} from store_sales group by ss_item_sk, ss_quantity"
spark.sql(sql).write.parquet("output.parquet")
}
scala> spark.time(bench("first_value"))
Timetaken: 320671 ms
scala> spark.time(bench("min"))
Timetaken: 64462 ms
I don't understand why there would be such a significant performance difference between first_value and min. I will try to reproduce this in DataFusion next.
Running the same benchmark in a branch where I am working on the upgrade to DataFusion 47.0.0, I see that performance is greatly improved and is actually faster than Spark 🚀
scala> spark.time(bench("first_value"))
Time taken: 69429 ms
Here is a run with the original query that took 77 seconds in Spark:
scala> spark.time(spark.read.parquet("/mnt/bigdata/tpcds/sf100/store_sales.parquet").repartition($"ss_item_sk").dropDuplicates(Seq("ss_item_sk", "ss_quantity")).write.parquet("output44.parquet"))
Time taken: 62956 ms
Running the same benchmark in a branch where I am working on the upgrade to DataFusion 47.0.0, I see that performance is greatly improved and is actually faster than Spark 🚀
scala> spark.time(bench("first_value"))
Time taken: 69429 ms
Activity
andygrove commentedon Jan 13, 2025
Disabling Comet aggregation improves performance from 230s to 64s and is slightly faster than Spark at 78s.
andygrove commentedon Apr 8, 2025
I ran this test again with latest from main. I used this script to launch spark-shell:
I ran this query
With Comet: 325s
With Spark: 77s
Observations with Comet:
Observations with Spark:
andygrove commentedon Apr 8, 2025
I filed #1625 for implementing a native Parquet writer so that we can avoid the C2R conversion.
andygrove commentedon Apr 8, 2025
Sample native plan with metrics:
andygrove commentedon Apr 8, 2025
The performance issue seems specific to the
first_valueaggregate function. ThedropDuplicatescall is equivalent to:Using
mininstead offirst_valueis much faster.Here is how I tested:
I don't understand why there would be such a significant performance difference between
first_valueandmin. I will try to reproduce this in DataFusion next.andygrove commentedon Apr 8, 2025
There was a recent improvement in DataFusion that may help. I will test.
apache/datafusion#15266
andygrove commentedon Apr 8, 2025
Running the same benchmark in a branch where I am working on the upgrade to DataFusion 47.0.0, I see that performance is greatly improved and is actually faster than Spark 🚀
Thanks @2010YOUY01 😄
andygrove commentedon Apr 8, 2025
Here is a run with the original query that took 77 seconds in Spark:
2010YOUY01 commentedon Apr 9, 2025
The credit should go to @UBarney 🚀
andygrove commentedon Apr 17, 2025
This should be resolved now that we have upgraded to DF 47