Skip to content

perf(lakehouse): store hot-projection keys once, 6.9 GB to 1.1 GB - #48

Merged
Stanback merged 1 commit into
mainfrom
perf/compact-hot-store
Oct 24, 2026
Merged

Stanback merged 1 commit into
mainfrom
perf/compact-hot-store

Conversation

@Stanback

Copy link
Copy Markdown
Owner

The local SQLite hot projection repeated 64-character hashed keys in the table and in every index, plus an implicit primary-key index. That came to 6.9 GB, about 813 bytes a race.

  • Swimmer, meet and event keys live once in dimension tables. The race table and its athlete_history and meet_results indexes hold only integers. Rows are inserted clustered by swimmer and date, and a races view keeps the original columns.
  • lakehouse.py rebuild-hot replaces the projection from the committed Iceberg snapshot. The snapshot ID is unchanged.

Measured on the national checkpoint, 8,506,767 races:

Before After
Hot SQLite store 6,915.5 MB (812.9 B/row) 1,101.6 MB (129.5 B/row)
History lookup, first / warm median 0.168 / 0.012 ms 0.311 / 0.020 ms

Lookups are slightly slower because of the join to the swimmer table. The remaining bulk is the race ID, stored once per row.

Parity checks:

  • Per course and category, the race count, summed times, distinct swimmers and meets, and date range all match Iceberg.
  • 498 sampled swimmer histories match.
  • probe passes.

Tests: TURNMARK_LAKEHOUSE_TESTS=1 python -m unittest discover -s research/conversion-model passes (108), including a new test that rebuild-hot restores a corrupted projection from the pinned snapshot. render_report_tables.py --check passes.

🤖 Generated with Claude Code

The SQLite hot projection repeated 64-character hashed keys in the table and
in every index, plus an implicit primary-key index: about 813 bytes a race.
Swimmer, meet and event keys now live once in dimension tables; the race
table and its athlete-history and meet-results indexes hold integers, rows
are inserted clustered by swimmer and date, and a `races` view keeps the
original columns. Uniqueness of (source, race_id) is already enforced when
the snapshot is read, so no index carries race_id.

`lakehouse.py rebuild-hot` replaces the projection from the committed Iceberg
snapshot without touching it. On the national checkpoint (8,506,767 races,
snapshot 4441271835344284414) the store is 1,101,565,952 bytes, 129.5 bytes a
race; per-course/category totals and 498 sampled swimmer histories match
Iceberg, and warm history lookups take about 0.02 ms (0.012 before; the cost
is the join to the swimmer table). Receipt, REPORT appendix and lakehouse
notes updated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@Stanback
Stanback merged commit 9d713be into main Oct 24, 2026
13 checks passed
@Stanback
Stanback deleted the perf/compact-hot-store branch October 24, 2026 19:30
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