Skew Join Salting Key in Python (Demo)

Demonstrates skew join salting by expanding a smaller side with salt keys and matching rows on the larger side via random salt assignment.

Medium Python 3.9+ Aug 9, 2026 Big data & Spark 14 views 0 copies

Python code

47 lines
Python 3.9+
import random


def skew_join_salting_key(left_df, right_df, salt_range=4):
    """
    Demonstrates skew join salting: expand the smaller side with salt keys,
    then attach a salt key to each row on the larger side.
    Returns a list of (left, right, salt) tuples.
    """
    skewed_left = []
    for row in left_df:
        for salt in range(salt_range):
            skewed_left.append((row, salt))

    joined = []
    for l_row, salt in skewed_left:
        for r_row in right_df:
            if r_row["key"] == l_row["key"] and r_row["salt"] == salt:
                joined.append((l_row, r_row["value"], salt))
    return joined


if __name__ == "__main__":
    # Simulate a small 'right' side (dimension table) with prefixed salt keys
    right_df = [
        {"key": "A", "salt": 0, "value": "x"},
        {"key": "A", "salt": 1, "value": "y"},
        {"key": "B", "salt": 0, "value": "z"},
    ]

    # Large left side: each row will pick a random salt in [0, salt_range)
    left_df = [
        {"key": "A", "id": 101},
        {"key": "A", "id": 102},
        {"key": "B", "id": 103},
    ]

    # Assign a random salt to each left row (simulating a distributed join)
    random.seed(42)
    left_df_with_salt = []
    for row in left_df:
        row["salt"] = random.randrange(4)
        left_df_with_salt.append(row)

    result = skew_join_salting_key(left_df_with_salt, right_df)
    for l, r, salt in result:
        print(f"left_id={l['id']} key={l['key']} right_value={r} salt={salt}")

Output

stdout
left_id=101 key=A right_value=x salt=0
left_id=101 key=A right_value=y salt=1
left_id=102 key=A right_value=x salt=0
left_id=102 key=A right_value=y salt=1
left_id=103 key=B right_value=z salt=0

How it works

Skew join salting mitigates hot-key skew in distributed joins by adding a salt dimension to the smaller side and randomly assigning salts to rows on the larger side. The skew_join_salting_key expands the left (large) side with all salt values, then matches exact key+salt pairs against the pre-salted right side. Using random.seed(42) ensures reproducible salt assignments, so the output is deterministic. This mimics a real Spark-style salted join where shuffle keys are balanced across partitions. The approach trades extra memory for balanced compute distribution.

Common mistakes

  • Forgetting to seed random for reproducible test output
  • Assigning salts on the wrong side (should be the large side)
  • Using a salt_range too small to actually reduce skew
  • Mismatching salt values between the two sides

Variations

  1. Use `itertools.product` to generate salt-expanded rows more concisely
  2. Replace random assignment with a hash-based salt (e.g., `row['key'] % salt_range`) for stable bucketing

Real-world use cases

  • Balancing joins between a huge fact table and a small dimension table in PySpark batch jobs.
  • Reducing hot-key bottlenecks when aggregating user events by user_id in streaming pipelines.
  • Preventing out-of-memory errors in distributed SQL engines during high-cardinality key joins.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Big data & Spark

Related tutorials and quizzes for this topic.