xumingming opened a new pull request, #58144:
URL: https://github.com/apache/spark/pull/58144

   ### What changes were proposed in this pull request?
   
   Turn `TransposeWindow` into a whole-chain reordering rule so that a stack of
   adjacent `Window` operators connected by transparent projections is reordered
   to insert the fewest possible exchanges. Windows are grouped by the minimal
   partition spec their partition spec contains (smaller spec first within a
   group), so every member of a group rides the group leader's exchange; the
   result needs one exchange per minimal partition spec, which is the provable
   lower bound. When a `Filter` pins the top window (an `InferWindowGroupLimit`
   rank pattern), only the windows below it are reordered, preserving the strict
   `Filter`-over-`Window` shape.
   
   The behavior is gated behind the internal
   `spark.sql.optimizer.windowReorder.enabled` config (default `false`), and the
   partition-spec subset reasoning honors
   `spark.sql.requireAllClusterKeysForDistribution`.
   
   ### Why are the changes needed?
   
   A stacked-window query with interleaved partition specs pays one `Exchange`
   per distinct spec layer, because a window can only ride an existing exchange
   when its spec is a superset of that key, and the adjacent-pair-only
   `TransposeWindow` cannot fix an interleaving where a superset window appears
   above (not below) its subset. For example, the three specs below all share 
the
   user key, yet the ASC/DESC interleaving forces one exchange per layer:
   
   ```sql
   SELECT user_id,
     ROW_NUMBER() OVER (PARTITION BY user_id, is_primary        ORDER BY 
create_ts)      AS rn_user,
     ROW_NUMBER() OVER (PARTITION BY user_id, tier, is_primary  ORDER BY 
create_ts)      AS rn_user_tier,
     ROW_NUMBER() OVER (PARTITION BY user_id, model, priority   ORDER BY 
create_ts)      AS rn_user_model,
     ROW_NUMBER() OVER (PARTITION BY user_id, is_primary        ORDER BY 
create_ts DESC) AS rn_user_desc,
     ROW_NUMBER() OVER (PARTITION BY user_id, tier, is_primary  ORDER BY 
create_ts DESC) AS rn_user_tier_desc,
     ROW_NUMBER() OVER (PARTITION BY user_id, model, priority   ORDER BY 
create_ts DESC) AS rn_user_model_desc,
     LAG (create_ts) OVER (PARTITION BY user_id, tier, is_primary ORDER BY 
create_ts)    AS prev_create_ts
   FROM serving_log
   ```
   
   Reordering collapses repeated and subset-related specs onto shared exchanges
   (`HashPartitioning(user_id, is_primary)` rides every `(user_id, tier,
   is_primary)` window, so two exchanges suffice). In a production ETL with 13
   stacked windows, this cuts window exchanges from 8 to 3 and avoids ~1.7 TiB 
of
   shuffle per run; a committed microbenchmark measures ~1.3X on the 16M-row
   interleaved shape above. See SPARK-58891.
   
   ### Does this PR introduce _any_ user-facing change?
   
   No. The reordering is an internal, opt-in optimization (default `false`), so
   existing plans are unchanged unless the config is enabled.
   
   ### How was this patch tested?
   
   - Extended `TransposeWindowSuite` with stack-reordering cases (minimal-spec
     grouping, idempotence, transparent links, pin-top with rank filters,
     determinism/reference/empty-spec guards, 
`requireAllClusterKeysForDistribution`
     interaction).
   - Added `WindowStackExchangeSuite` (physical) asserting the resulting
     exchange counts, and `WindowReorderBenchmark` with a committed results
     snapshot.
   - Ran the window optimizer suites, `DataFrameWindowFunctionsSuite`,
     `SQLWindowFunctionSuite`, window-frames and `EnsureRequirementsSuite`;
     scalastyle clean for both main and test sources.
   
   ### Was this patch authored or co-authored using generative AI tooling?
   
   Generated-by: Pi
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to