perf: structural SQL optimizations for search, views, latest, NextUp & projection caching #6

Merged
Wuast94 merged 8 commits from perf/structural-sql-readmodel into main 2026-10-19 11:41:08 +02:00
Owner

Zusammenfassung

Dieser PR adressiert die verbleibenden strukturellen Latenzen von rustfin über 5 zielgerichtete Blueprints:

  1. Search (Blueprint 1):

    • Kommutator für GIN-Trigramm-Operator in postgres/store/search/plan.rs (column %> text statt text <% column), wodurch der PostgreSQL GIN-Trigramm-Index search_titles_text_gin_idx aktiviert wird.
    • Migration m20261019_000044_search_query_dedup.rs dedupliziert generierte tsquery-Terme.
    • search_predicate_ids_scoped lädt nur noch Items mit tatsächlichem Inhaltsbezug (require_content: true), wodurch 2.200+ unbeteiligte Filme bei Personen-Treffern vermieden werden.
    • Nicht-physische Items werden in cursor.rs über visible_metadata_page in einem einzigen Batch statt N Einzelqueries geholt.
  2. Views (Blueprint 2):

    • Deduplizierung der Hierarchy Candidates CTE in postgres/store/catalog_readmodel/physical.rs (rekursive Kandidaten traversieren nur noch einmal).
    • Ordner-Nachfahren werden in summary/scope.rs nur noch expandiert, wenn needs.grouped_folders aktiv ist (reduziert Suchraum von 17.378 auf 250 direkte Kinder).
    • Kind-Kompositionen (BoxSet) werden nun direkt in SQL innerhalb von members, direct und logical in native_composition/plan.rs unterstützt.
  3. Latest (Blueprint 4):

    • Unbenutzte Relationen (named_ids, composition_ids, versions, user_data) in api/latest/facts.rs gestrippt.
    • Sequentielle 16-Schleifen-Abfrage von visible_catalog_item_metadata in api/latest/grouping.rs durch visible_metadata_page gebündelt.
    • Native Folder Summaries für Container (Folder, MusicAlbum, PhotoAlbum).
  4. NextUp (Blueprint 3):

    • catalog_started_episode_history in selection.rs nutzt nun DISTINCT ON (series_id) ORDER BY series_id, last_played DESC – statt 10.000 Episoden werden nur noch 10–50 Zeilen geladen.
    • Fast-Path in select_with_options: Wenn options.ordered_ids die exakte Kandidatenliste vorgibt und keine Sorts/Filter vorliegen, wird der teure collect_fallback und CatalogPredicateRead komplett umgangen und direkt gesliced.
  5. Projection Batching & Server Configuration Cache (Blueprint 5):

    • In-Memory RwLock-Cache in Store für installation() (ServerSettings) und root_configuration() (ServerConfiguration), atomar invalidiert/aktualisiert bei Writes. Eliminiert 30–100 redundante SQL-Queries pro HTTP-Request.
    • Page::project_all bündelt die DTO-Projektion und eliminiert die 32–64 sequentiellen http::cpu-Thread-Pool-Hops in execution.rs und latest/mod.rs.

Verifikation

  • just architecture ok
  • just fmt-check ok
  • just clippy ok (-D warnings)
  • just deny ok (advisories ok, bans ok)
  • just machete ok (0 unused dependencies)
  • just schema-check ok
  • just test vollständig grün (alle 131 identity_api_tests, alle 82 store_tests, alle unit/integration tests)
## Zusammenfassung Dieser PR adressiert die verbleibenden strukturellen Latenzen von rustfin über 5 zielgerichtete Blueprints: 1. **Search (Blueprint 1):** - Kommutator für GIN-Trigramm-Operator in postgres/store/search/plan.rs (column %> text statt text <% column), wodurch der PostgreSQL GIN-Trigramm-Index search_titles_text_gin_idx aktiviert wird. - Migration m20261019_000044_search_query_dedup.rs dedupliziert generierte tsquery-Terme. - search_predicate_ids_scoped lädt nur noch Items mit tatsächlichem Inhaltsbezug (require_content: true), wodurch 2.200+ unbeteiligte Filme bei Personen-Treffern vermieden werden. - Nicht-physische Items werden in cursor.rs über visible_metadata_page in einem einzigen Batch statt N Einzelqueries geholt. 2. **Views (Blueprint 2):** - Deduplizierung der Hierarchy Candidates CTE in postgres/store/catalog_readmodel/physical.rs (rekursive Kandidaten traversieren nur noch einmal). - Ordner-Nachfahren werden in summary/scope.rs nur noch expandiert, wenn needs.grouped_folders aktiv ist (reduziert Suchraum von 17.378 auf 250 direkte Kinder). - Kind-Kompositionen (BoxSet) werden nun direkt in SQL innerhalb von members, direct und logical in native_composition/plan.rs unterstützt. 3. **Latest (Blueprint 4):** - Unbenutzte Relationen (named_ids, composition_ids, versions, user_data) in api/latest/facts.rs gestrippt. - Sequentielle 16-Schleifen-Abfrage von visible_catalog_item_metadata in api/latest/grouping.rs durch visible_metadata_page gebündelt. - Native Folder Summaries für Container (Folder, MusicAlbum, PhotoAlbum). 4. **NextUp (Blueprint 3):** - catalog_started_episode_history in selection.rs nutzt nun DISTINCT ON (series_id) ORDER BY series_id, last_played DESC – statt 10.000 Episoden werden nur noch 10–50 Zeilen geladen. - Fast-Path in select_with_options: Wenn options.ordered_ids die exakte Kandidatenliste vorgibt und keine Sorts/Filter vorliegen, wird der teure collect_fallback und CatalogPredicateRead komplett umgangen und direkt gesliced. 5. **Projection Batching & Server Configuration Cache (Blueprint 5):** - In-Memory RwLock-Cache in Store für installation() (ServerSettings) und root_configuration() (ServerConfiguration), atomar invalidiert/aktualisiert bei Writes. Eliminiert 30–100 redundante SQL-Queries pro HTTP-Request. - Page::project_all bündelt die DTO-Projektion und eliminiert die 32–64 sequentiellen http::cpu-Thread-Pool-Hops in execution.rs und latest/mod.rs. ## Verifikation - just architecture ok - just fmt-check ok - just clippy ok (-D warnings) - just deny ok (advisories ok, bans ok) - just machete ok (0 unused dependencies) - just schema-check ok - just test vollständig grün (alle 131 identity_api_tests, alle 82 store_tests, alle unit/integration tests)
fix(websocket): observe websocket cancellation in heartbeat worker to prevent shutdown race
All checks were successful
CI / Quality (pull_request) Successful in 1h2m14s
CI / Build production (pull_request) Successful in 26m30s
0a16536c6d
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Wuast94/rustfin!6
No description provided.