Repository navigation
Aggregate entity and relation usage counts in ontology views to avoid correlated table scans - #1088
Merged
WaylandYang merged 1 commit intoOct 5, 2026
Conversation
…eries with LEFT JOIN aggregations and concurrent fetch (cherry picked from commit eae3d45b46671e96456060fc92a07e1e09b9bee9) Signed-off-by: Jun Du <dujun@tib.cas.cn>
WaylandYang
approved these changes
Oct 5, 2026
WaylandYang
left a comment
Contributor
There was a problem hiding this comment.
Thanks @plpycoin. Measured on a database with the dev schema: one base with 3,000 classes, 90,000 entities, 300 properties and 200,000 facts, beside another base's 60,000 entities.
| Usage counts | Before | After |
|---|---|---|
| Classes | 7.9 s | 9 ms |
| Properties | 1.4 s | 14 ms |
Same counts on both sides. The correlated count had no index to seek with (entities and facts both lead their indexes with kb_id), so it scanned once per class; one grouped pass over the base's own rows is the right shape. Running the four reads of the ontology page together is fine too. Landing it.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
In
utopia-store::ontology::entity_type_viewsandrelation_type_views, usage counts for each entity type and relation type were computed via correlated subqueries in theSELECTlist:(SELECT count(*) FROM entities e WHERE e.type_id = t.id AND e.merged_into IS NULL) AS usage(SELECT count(*) FROM facts f WHERE f.predicate_id = r.id AND f.invalidated_at IS NULL) AS usageOn knowledge bases with large ontologies (e.g. imported vocabularies with thousands of classes) and tens/hundreds of thousands of entities and facts:
entitieshas no single-column index ontype_id, and omittinge.kb_id = t.kb_idprevents Postgres from utilizingentities_kb_type_name_idx. For every entity type in the KB, Postgres executes a sequential scan of the entireentitiestable. For a KB with ~9,700 classes and 89,000 entities, this leads to ~8.7x10^8 row inspections and takes ~70 seconds.factshas no index withpredicate_idas the leading column, leading to sequential scans offactsfor each relation type (~10 seconds).ontology_routes::get, these queries were executed sequentially, causingGET /api/v1/kbs/:kb_id/ontologyto take 80+ seconds and easily hit reverse proxy timeouts (such as nginx 60s gateway timeouts).What changes
entity_type_viewsandrelation_type_viewsincrates/utopia-store/src/ontology.rsto aggregate usage counts per knowledge base once (GROUP BY type_id/GROUP BY predicate_id) andLEFT JOINthe result ontoentity_typesandrelation_types.crates/utopia-server/src/api/ontology_routes.rs, fetch entity types, relation types, and misses concurrently usingtokio::try_join!.Benchmarks (measured on KB with 9,740 classes and 372 relations):
entity_type_viewsquery: ~70,139 ms -> 125 ms (~560x speedup)relation_type_viewsquery: ~10,170 ms -> 5.4 ms (~1880x speedup)GET /api/v1/kbs/:kb_id/ontologyresponse: ~78 s -> 0.62 s (~125x speedup)How it was checked
cargo fmt --all --checkcargo clippy -p utopia-store -p utopia-server --all-targets -- -D warningscargo test -p utopia-store(unit and store integration tests pass)cargo test -p utopia-server ontology(18 ontology route tests pass)entity_types,relation_types,usagecounts) remains identical.Before review
git commit -s)cargo fmt --all --check,cargo clippy --workspace --all-targets -- -D warningsandcargo test --workspacepasscrates/utopia-store/was tested withUTOPIA_DATABASE_URLset (those tests skip without it)