Skip to content

feat: shuffle skew detection + bloom filter pre-filtering - #5

Merged
cigrainger merged 2 commits into
mainfrom
cg/distributed-improvements-2
Mar 23, 2026
Merged

cigrainger merged 2 commits into
mainfrom
cg/distributed-improvements-2

Conversation

@cigrainger

Copy link
Copy Markdown
Contributor

Summary

  • Shuffle skew detection: After hash-partitioning both sides of a shuffle join, inspects bucket sizes and emits [:dux, :distributed, :shuffle, :skew_detected] telemetry when any bucket exceeds 5× the mean. Adds configurable :over_partition_factor option (default 4).
  • Bloom filter pre-filtering for broadcast joins: Before broadcasting the full right table, extracts distinct join keys and broadcasts them first. Workers pre-filter the left side with IN (SELECT ...) before the main join, reducing bandwidth for selective joins. Only applies to :inner and :left joins (skipped for anti/right joins where filtering would drop needed rows). Skipped when distinct key count > 10,000.
  • Benchmarks: Adds shuffle join (100K×100K) and broadcast+bloom (100K×20) benchmark sections. Fixes version naming in history.csv to use SHA-based identifiers.

Test plan

  • 505 tests pass, 0 failures (3× stable runs)
  • 0 credo issues
  • Shuffle join benchmark: 1,500ms (near parity with 1,480ms local)
  • Broadcast+bloom benchmark: 4.68ms distributed vs 2.97ms local
  • Verify distributed peer tests pass on CI

🤖 Generated with Claude Code

cigrainger and others added 2 commits March 23, 2026 13:28
…st joins

Shuffle skew detection:
- detect_skew/3 inspects bucket sizes after hash-partitioning
- Heavy buckets (>5x mean) emit [:dux, :distributed, :shuffle, :skew_detected]
  telemetry with bucket IDs and sizes
- New :over_partition_factor option for user tuning (default 4)

Bloom filter pre-filtering:
- Before broadcasting full right table, extract and broadcast distinct join
  keys as a separate table
- Workers pre-filter their left partition with IN (SELECT key FROM keys_table)
- DuckDB optimizes this as a semi-join internally
- Only for :inner/:left joins (anti/semi need unfiltered left)
- Skip if right has >10K distinct keys (filter wouldn't help)
- Keys table cleaned up with other broadcast tables

Fixes:
- Multi-column COUNT DISTINCT: use subquery instead of COUNT(DISTINCT a, b)
- Anti join: skip bloom filter (would eliminate rows we want to keep)

505 tests (43 doctests + 11 properties + 451 tests), 0 failures.
3x consecutive runs confirmed stable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds two new benchmark sections: shuffle join (100K×100K) and broadcast
join with bloom filter pre-filtering (100K×20). Fixes the version column
in history.csv to use SHA-based identifiers instead of non-existent tags.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cigrainger
cigrainger merged commit 1156df5 into main Mar 23, 2026
3 checks passed
@cigrainger
cigrainger deleted the cg/distributed-improvements-2 branch March 23, 2026 02:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant