databrickslabs / databrickslabs/ontos

[Perf]: Push data-catalog pagination/filters into SQL (perf follow-up to #337)

Open
#409 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type/perf
Dominant language
Python
Stars
212
Forks
71
Avg merge
4d 10h
Merged PRs (30d)
43

Description

Background

PR #337 (data-catalog overhaul) introduced server-side pagination, faceted hierarchy filters, and full-field search. The API contract is correct, but the implementation does the filtering/paging in Python after pulling all contract + asset columns end-to-end on every request.

Reviewer flagged this in https://github.com/databrickslabs/ontos/pull/337#pullrequestreview-... — we agreed to ship #337 with the known-follow-up disclaimer and track the proper fix here.

Hot path

Every one of these endpoints, on every page click and every debounced keystroke, re-pays the full merge cost:

  • GET /api/data-catalog/columnsDataCatalogManager.get_all_columns
  • GET /api/data-catalog/columns/searchDataCatalogManager.search_columns
  • GET /api/data-catalog/hierarchyDataCatalogManager.get_hierarchy_filters
  • GET /api/data-catalog/tablesDataCatalogManager.get_table_list

All four call _get_columns_from_contracts() + _get_columns_from_assets() + _merge_columns() and then slice in Python:

  • In-memory list slice (search): src/backend/src/controller/data_catalog_manager.py around L540–555
  • In-memory list slice (list view): src/backend/src/controller/data_catalog_manager.py around L580–585

For tenants with thousands of registered columns this is O(N) per request, multiplied by typing speed.

Proposed direction

  1. Push the facet filters (catalog / schema / asset_type / system / table) into the SQLAlchemy query against assets + data_contract_schema_properties.
  2. Use LIMIT / OFFSET (or keyset pagination keyed on (table_full_name, column_name)) at the DB layer.
  3. Compute total_count via a single COUNT(*) over the same filtered query, not by materialising the full set.
  4. Move _matches_search predicates into the query as ILIKE / tsvector matches. Postgres tsvector over (column_name, description, label, table_name, contract_name, system_name, catalog_name, schema_name, business_terms_text) is probably the right shape long-term.
  5. Keep the merge/dedup step but apply it only to the page slice, not the universe.

Constraints

  • Contract columns live in data_contract_schema_properties joined via data_contract_schema_objects and data_contracts.
  • Asset columns live as child assets linked by asset_relationships.relationship_type = 'hasColumn'. The hierarchy traversal (System/Catalog/Schema parents) currently happens in Python via _resolve_asset_parents — that would either need a recursive CTE or a materialised denormalised view.
  • Dedup key is case-insensitive on (table_full_name, column_name) and the 'both' source flag must survive.

Done when

  • A 10K-column tenant returns a page in < 200ms for any of the four endpoints under realistic filter combinations.
  • total_count is exact, not estimated.
  • No regression in the merge/dedup tests added in #337 (src/backend/src/tests/unit/test_data_catalog_manager.py).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/backend/src/controller/data_catalog_manager.py at get_all_columns, search_columns, get_hierarchy_filters, get_table_list, and the _get_columns_from_contracts/_get_columns_from_assets/_merge_columns path. Read src/backend/src/tests/unit/test_data_catalog_manager.py and run its merge/dedup tests before tracing the SQLAlchemy models and joins. Done means all four endpoints filter, paginate, count exactly, preserve dedup behavior, and meet the stated 10K-column latency target.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgresql, python, sqlalchemy
Domain
backend-api-design, databases, performance
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.