Same-commit re-crawl is unusably slow on large repositories
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 17
- Forks
- 5
- PR merge metrics
- No merged PRs in 30d
Description
Re-crawling a finished database at the same commit should be close to free: nothing has changed, so the crawl should verify that and stop. @davidh233's team measured 67 to 92s on a small repository, and on a larger one the classify stage alone had not finished after 19 minutes. That makes incremental refresh impractical at monorepo scale, which is most of the reason to run a crawl on a schedule at all.
The cost is in the read path, and it is the mirror image of #83. There is no scalar index on row_id, so every point lookup scans every fragment of the whole table. The crawl does two of those per file: classify looks up each file's sentinel to decide skip versus redo, and add_label reads back each existing file's chunk rows to confirm they still carry the label. Neither stage writes anything on a same-commit re-crawl. They read everything to find there is nothing to do.
Fragment count multiplies all of it, since a scan crosses every fragment, and fragments accumulate with every checkpoint commit.
Investigation
Their measurements, per-file against batched, on two copies of the same database:
| Scenario | Per-file | Batched |
|---|---|---|
| Small repository, freshly built (94 fragments) | 92s | 2-3s |
| Small repository, after compaction (1 fragment) | 16s | 1s |
| Large repository, freshly built (1,342 fragments) | classify unfinished at 19 min | 255s |
| Large repository, after compaction (1 fragment) | 1,134s | 19s |
Batching is worth two orders of magnitude on the scan count. Compaction is worth another large factor on top, which is a separate problem and gets its own issue.
Proposed fix
Both stages get the same treatment as #83: replace per-file lookups with row_id IN (...) and file_id IN (...) predicates over bounded batches.
Four pieces, one PR:
-
Batched sentinel read. A
get_sentinel_statuseshelper taking a slice of sentinelrow_ids and returning a status map. Classify computes allfile_ids locally, fetches the map in one batched call, then classifies in the original file order sonew_filesstill comes out in upstream order. -
Batched chunk read for add_label. A
get_chunks_by_file_idshelper batching byfile_id IN, regrouping rows per file before the existing per-file verification runs. This is the piece with real logic in it. -
Batch size. Reuse the existing
UPSERT_BATCH_SIZErather than introducing 200 as a second constant, unless there is a measured reason it differs here. -
No per-file fallback on batch failure. Their version catches a batch-level error and retries that batch row by row. I would rather not: a failed read is a real error, retrying per file turns it into a slow success nobody notices, and it doubles the paths through classify while being almost never exercised. @davidh233, if you hit something concrete that motivated the fallback, I would like to know what it was, since if it was predicate length that is a batch-size question with a different answer.
Related
#83 batches the write side of the same pattern, the per-file completion marks at checkpoints.
#84 retires the sentinel mechanism, which removes piece 1 entirely. Piece 2 survives it, since the label verification read has nothing to do with the sentinel. This issue is worth doing first regardless: #84 is a schema change with a longer investigation ahead of it, and re-crawls are unusable on large repositories until then.
@LPegasus
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the classify and add_label read paths, then inspect the existing UPSERT_BATCH_SIZE usage and the batching approach from issue #83. Implement the batched sentinel and chunk reads while preserving file order and existing per-file verification; done means same-commit re-crawls avoid per-file scans and retain their current behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100