Multi-Stage Hash Join Techniques
- Multi-stage hash join is a family of techniques that decomposes join processing into discrete stages to control intermediate-result growth, balance load, and minimize data movement.
- It employs varied execution models, such as three-stage pipelines on accelerators, hot-key based splits in distributed systems, and Lookup/Expand in column stores.
- These methods optimize performance by tailoring join operations to hardware capacities, network conditions, and workload skew, reducing DRAM and network costs.
Searching arXiv for the cited works and closely related terminology. Multi-stage hash join is a family of join-processing strategies that decomposes hash-based join evaluation into multiple explicit phases rather than treating a join as a single monolithic build-and-probe operator. In the literature, this decomposition appears in several distinct but related forms: a three-stage streaming pipeline for multiway joins on coarse-grain reconfigurable hardware; a multistage distributed architecture that isolates hot and cold keys and assigns each sub-join to a different execution method; and a logical decomposition of hash join into Lookup and Expand operators for acyclic joins in column stores (Olukotun et al., 2019, Metwally, 2022, Bekkers et al., 2024). Across these settings, the common objective is to control intermediate-result growth, reduce data movement, and improve load balance by making the stages of join evaluation explicit.
1. Scope and conceptual variants
The term encompasses several execution models rather than a single algorithmic template. In "Efficient Multiway Hash Join on Reconfigurable Hardware" (Olukotun et al., 2019), a classic three-way join
is implemented as a three-stage streaming pipeline consisting of global partitioning, per-partition build, and nested probing. In "Scaling and Load-Balancing Equi-Joins" (Metwally, 2022), Adaptive-Multistage-Join (AM-Join) decomposes an equi-join into four disjoint sub-joins according to whether a key is hot or cold in each input, and then assigns those sub-joins to Tree-Join, Index-Broadcast-Join, or a standard shuffle join. In "Instance-Optimal Acyclic Join Processing Without Regret: Engineering the Yannakakis Algorithm in Column Stores" (Bekkers et al., 2024), hash join is decomposed into Lookup and Expand in Nested Semijoin Algebra (NSA), then executed through shredding in a column-store engine.
These formulations differ in substrate, data model, and optimization target. The hardware-oriented formulation emphasizes on-chip scratchpad capacity, static on-chip communication, and DRAM traffic (Olukotun et al., 2019). The distributed formulation emphasizes skew tolerance, shared-nothing scalability, and outer-join support without record deduplication or custom table partitioning (Metwally, 2022). The column-store formulation emphasizes robustness against large intermediates for acyclic queries and a no-regret transformation from a binary join plan to a 2-phase NSA plan (Bekkers et al., 2024).
A plausible implication is that "multi-stage hash join" is best treated as an execution principle: the operator is factored into stages that expose structure relevant to the target system, such as partition locality, skew class, or output reconstruction.
2. Stage decompositions in representative systems
The three works instantiate staging in sharply different ways.
| Setting | Stages | Primary purpose |
|---|---|---|
| Plasticine multiway join | Partitioning, build, probe | Avoid large intermediates and exploit CGRA locality |
| AM-Join | Hot-key discovery, HH/HC/CH/CC split, specialized sub-joins | Balance skew and minimize network movement |
| SYA / NSA | Lookup, then Expand / Flatten | Avoid large intermediates in acyclic joins |
In the Plasticine design, Stage 0 performs global partitioning. and are hashed on using a high-level hash into top-level partitions, while is hashed on using into 0 partitions; 1 is chosen so that 2, where 3 is on-chip capacity (Olukotun et al., 2019). Stage 1 loads one 4 from DRAM onto the chip and hashes each tuple 5 to one of 6 on-chip buckets via a second hash 7, building per-PMU hash tables keyed on 8. Stage 2 iterates over 9-side buckets: the corresponding 0 tuples with 1 are streamed into the same PMU tables, then 2 is streamed and broadcast to every PMU, where each PMU performs a small three-way match of its local 3- and 4-rows with the broadcast tuple and emits or aggregates the result on the fly (Olukotun et al., 2019).
AM-Join begins with hot-key identification. Let 5 and 6 be the sets of hot keys in 7 and 8. The result is decomposed as
9
where each quadrant is disjoint by construction (Metwally, 2022). Hot-hot keys are handled by Tree-Join, a multi-round split-and-shuffle join; hot-cold and cold-hot cases are handled by Index-Broadcast-Join (IB-Join), which builds a hash index on the small side, broadcasts it, and probes from the large side in one pass; cold-cold keys are handled by a standard single-round shuffle join (Metwally, 2022).
In the NSA-based formulation, a binary join such as 0 is decomposed into dictionary construction, a nested semijoin Lookup, and a later Expand:
1
The dictionary 2 maps each 3 to the bag of matching 4 values, Lookup attaches the corresponding nested bag to each tuple of 5, and Expand unnests it into flat output tuples (Bekkers et al., 2024). Shredded Yannakakis (SYA) transforms a binary join plan for an acyclic query into a 2-phase NSA plan in which lookup-like operators precede the final flattening phase (Bekkers et al., 2024).
3. Hardware realization: partition, build, and probe on a CGRA
The Plasticine-style accelerator is a tile-based CGRA organized as a 2D checkerboard of Pattern Memory Units (PMUs) and Pattern Compute Units (PCUs) (Olukotun et al., 2019). The described configuration has 6 PMUs and 7 PCUs arranged, for example, in an 8 layout, an on-chip total scratchpad of 9, SIMD PCUs with 0 lanes and peak 1 TFLOPS, a static high-bandwidth network supporting unicast, multicast, and broadcast, and off-chip DDR3 DRAM at 2 GB/s read/write (Olukotun et al., 2019). The memory hierarchy is
3
The execution mapping is explicitly stage-specific. Partitioning and join stages reconfigure the routing and PCU microcode on the fly, and all hash functions are synthesized as bit-shifts and xors in PCUs (Olukotun et al., 2019). During build, tuples of 4 are streamed into 5 disjoint per-PMU hash tables using 6. During probe, the 7 tuples stream in interleaved with build-table writes, collision handling in hardware is parallelized across PCUs, and each broadcast 8 tuple simultaneously probes the build tables for both 9 and 0 matches through a 2-level hash lookup (Olukotun et al., 2019). Double-buffered PMU banks overlap DRAM prefetch of the next partition with current join computation, and the entire chip is reconfigured once per top-level 1 partition, while the inner probe loops run freely (Olukotun et al., 2019).
This architecture is specifically motivated by the case where joining three or more relations in a single step is preferable because the join of any two relations would yield an excessively large intermediate relation (Olukotun et al., 2019). The implementation therefore treats staging not merely as a software pipeline but as a mapping of partition-local state, communication mode, and compute microcode onto a reconfigurable substrate.
4. Distributed multistage joins under skew
AM-Join addresses the case in which equi-joins become difficult because hot keys appear in both relations at large scale (Metwally, 2022). Its central design decision is to classify keys by hotness in each input and dispatch each quadrant of the decomposition to an appropriate operator.
The hot-key threshold is derived from a comparison between the cost of a single-round shuffle join, 2, and the cost of one Tree-Join splitter stage followed by processing of the resulting sublists. If a key has joined-list sizes 3 and 4, with effective size 5, then in the worst case a key is classified hot when
6
where 7 is the ratio of network cost to local I/O cost and 8 is the number of executors (Metwally, 2022). A simple sufficient threshold independent of 9 is
0
When a hot key is split, Tree-Join chooses a chunking exponent 1 such that the splitter cost 2 matches the downstream executor cost 3, giving 4. The resulting number of sub-lists per side is
5
and each sub-list has size
6
After 7 split rounds, each inherited sublist has size 8, and splitting stops once the hot threshold is no longer exceeded; the number of iterations satisfies
9
These are the formal basis for the claim that only a doubly logarithmic number of split rounds is needed (Metwally, 2022).
AM-Join also modifies the initial round to preserve balance. Tree-JoinBasic would hash all occurrences of a hot key onto one partition in the first iteration, so the load-balanced version first runs a distributed heavy-hitters procedure using Space-Saving plus treeAggregate to produce 0, then "unravels" the hot keys into an augmented-key index of sub-list pairs before Tree-JoinBasic proceeds (Metwally, 2022). The paper states that this avoids building a huge initial joined index for very hot keys and preserves randomness and balance even in round 1 (Metwally, 2022).
The same staging framework extends to outer joins. Table 2 of the paper states that AM-Join supports all outer-join kinds by selecting for each of the four sub-joins either Tree-Join, Index-Broadcast-Left-Outer-Join, or a shuffle variant of left, right, or full outer join, and no extra deduplication is needed because the sub-joins are disjoint and use standard outer-join semantics (Metwally, 2022).
5. Cost models and stage-selection criteria
The literature treats multistage hash join not only as an execution pattern but also as a planning problem governed by explicit cost models.
For the linear three-way join on Plasticine, the total number of DRAM tuples read onto the chip is
1
The interpretation given is that each 2 and 3 tuple is loaded exactly once, while each 4 tuple is reread once per top-level 5 partition, namely 6 times (Olukotun et al., 2019). For a cascaded binary plan that first computes 7 with 8, where 9 is the join-key distinct count, the approximate cost is
0
The paper notes that when 1, the second term incurs 2 passes over DRAM, so the cost balloons (Olukotun et al., 2019).
For cyclic three-way joins where keys are pairwise shared, the cost is
3
with optimal choice
4
yielding
5
These formulas formalize the dependence of multistage join cost on top-level partitioning and on-chip capacity (Olukotun et al., 2019).
AM-Join presents a different cost comparison. For a hot key processed on a single executor, the local I/O cost is 6. In Tree-Join, the splitter emits 7 sub-pairs at cost 8, network cost is 9, and each downstream executor also performs 0 local I/O, so the bottleneck becomes 1 rather than 2 (Metwally, 2022). For the hot-cold case, broadcast is chosen when the cost of broadcasting the small side does not exceed the shuffle cost of the large side:
- broadcast time of 3:
4
- shuffle time for 5:
6
The hot-key collection phase itself has cost
7
In the NSA formulation, the cost model is stated in terms of three convex, monotone unit-cost functions: 8 for building a hash map on 9 keys, 00 for 01 probes into a map of size 02, and 03 for emitting a column of 04 output tuples (Bekkers et al., 2024). A traditional flat hash join costs
05
In a 2-phase NSA plan, each Lookup costs 06, each build costs 07, and the final Flatten costs 08 (Bekkers et al., 2024). The paper’s two central guarantees are robustness, meaning asymptotic 09 time for a 2-phase NSA plan on an acyclic join, and no regret, meaning that for every well-behaved binary plan 10, its SYA rewriting incurs no more build, probe, or generation cost than 11, pointwise on every database (Bekkers et al., 2024).
These cost models support a consistent planning principle: choose a staged plan when it lowers DRAM traffic, network movement, or intermediate construction relative to a simpler binary or single-round alternative.
6. Empirical results, misconceptions, and practical interpretation
The reported empirical outcomes differ by setting but consistently show that staging is most valuable when a conventional hash join would suffer from large intermediates or severe skew.
On the Plasticine performance model with 12 PMUs/PCUs, DRAM bandwidth of 13 GB/s, and on-chip memory of 14 MB, the CPU baseline is single-threaded Postgres on Xeon E5-2697 (Olukotun et al., 2019). For a cascaded binary self-join over three copies of a "friends" relation 15 of size 16 and distinct count 17, the accelerator achieves 18 to 19 speedup over the CPU, with the best results when 20; if the intermediate spills, the bottleneck shifts from DRAM streaming to SSD at 21 MB/s (Olukotun et al., 2019). For a single linear three-way self-join, the implementation achieves up to 22 speedup relative to cascaded binary joins on the same hardware for 23 and 24, with the largest speedups when 25 is small or DRAM bandwidth is limited (Olukotun et al., 2019). In a star-join where the large fact table 26 has size 27 and two dimension tables 28 and 29 each have size 30 with 31, 32 and 33 fit entirely on chip and the single 3-way join yields up to 34 speedup over two binary joins (Olukotun et al., 2019).
AM-Join reports that on two relations with more than 35 and 36 records, record size 37 or 38 bytes, and Zipf skew parameter 39, AM-Join and Tree-Join scale nearly linearly in 40 up to 41 and tolerate 42 up to 43--44, whereas single-round Hash-Join and Spark3-Join break down above 45 (Metwally, 2022). The paper also reports a same-attribute self-join speedup of approximately 46 from pruning duplicate pairs in Tree-JoinBasic, and on real Uber trip data totaling 47 TB, only AM-Join and Tree-Join complete a same-attribute self-join in 48 Hrs while others time out at 49 Hrs (Metwally, 2022).
SYA is implemented in Apache DataFusion using Rust and Arrow, with binary-plan input orders taken from DuckDB’s optimizer, and evaluated on 50 acyclic queries drawn from JOB, STATS-CEB, and a CE graph workload (Bekkers et al., 2024). The paper states that all runs exclude planning, I/O, aggregation, and focus only on join time. On JOB, SYA improves 51 of queries with speedups up to 52; on STATS-CEB, 53 with speedups up to 54; on CE, 55 with speedups up to 56 (Bekkers et al., 2024). The abstract states that across the full suite, SYA improves performance for 57 of the queries with speedups up to 58, while the detailed summary later states that SYA outperforms traditional binary hash join on 59 of 60 queries (Bekkers et al., 2024). This difference reflects distinct summary points within the same source and should not be conflated into a single percentage without qualification.
Several misconceptions are corrected by these results. One is that multistage execution is synonymous with repeated repartitioning in distributed systems; the hardware and column-store formulations show staging through on-chip partition/build/probe and Lookup/Expand decomposition instead (Olukotun et al., 2019, Bekkers et al., 2024). Another is that multistage methods are only beneficial for pathological cases. The SYA results emphasize competitiveness even on common acyclic workloads, while the Plasticine and AM-Join results show that the largest gains arise precisely when intermediate-result blowup or skew would otherwise dominate execution (Olukotun et al., 2019, Metwally, 2022, Bekkers et al., 2024). A further misconception is that staging necessarily requires custom data placement or deduplication logic: AM-Join explicitly states support for all outer-join variants without record deduplication or custom table partitioning, and SYA states that no extra per-tuple callbacks or code generation is needed once the NSA plan is shredded (Metwally, 2022, Bekkers et al., 2024).
Taken together, these works present multi-stage hash join as a systems-level technique for restructuring join execution around the actual sources of cost: memory capacity and broadcast locality on accelerators, key skew and network movement in shared-nothing clusters, and intermediate-result avoidance plus vectorized reconstruction in column stores.