Short: A Window.orderBy(...) with no partitionBy — every row was shuffled into a single partition.
Detailed: Without partitionBy, Spark must order the whole dataset globally, so it plans an Exchange SinglePartition beneath WindowExec and one task processes everything. The stage shows exactly 1 task carrying the entire Shuffle Read plus a large Spill (Disk) while the rest of the cluster idles.
Senior: Reduce first, then order: filter or pre-aggregate to candidates, or rank within real partitions and stitch them with a small per-partition offset table. A truly global ordering over billions of rows is a design problem, not a tuning knob.
Common mistake: Diagnosing it as skew and salting a key that the window does not even partition by.
Follow-up: How do you compute a global row number without a single-task stage?
Lesson · Simulation