← Back to all stagesStage 2
Stage 28: Hash Join
Concept
Implement a hash-based join algorithm that is dramatically faster than nested loop join for large tables with equality conditions.
What It Teaches
- Build phase: Scan the smaller (build) table and insert each row into an in-memory hash table, keyed by the join column.
- Probe phase: Scan the larger (probe) table. For each row, look up the join column in the hash table. If found, emit the joined row.
- O(N+M) vs O(N×M): Hash join is linear in the total number of rows, compared to nested loop's quadratic cost. The student sees a dramatic performance difference.
- When hash join is applicable: Only works for equality joins (
=), not range joins (>). - Memory trade-off: The hash table must fit in memory. If it doesn't, the student learns about partitioned (grace) hash join.
- Planner integration: The cost-based optimizer should prefer hash join when both sides are large.
Learning Objectives
- Implement
HashJoinNodePlanNode with build and probe phases. - Build a hash table from the smaller input during
Init(). - During
Next(), probe the hash table for each row of the larger input. - Handle hash collisions (multiple rows with the same join key).
- Update the planner to choose HashJoin vs NestedLoopJoin based on estimated table sizes.
- Update
explainto show the chosen join algorithm.
Explain Output
[PLAN] SELECT * FROM users JOIN orders ON users.id = orders.user_id
[PLAN] └── HashJoin (on: users.id = orders.user_id)
[PLAN] ├── SeqScan (table=users) [build]
[PLAN] └── SeqScan (table=orders) [probe]