catalog-backend: fix facets endpoint performance regression
Route the EXISTS-based filters through final_entities (one row per entity) instead of correlating against the search table directly. This avoids the pathological case where correlated subqueries scan the much larger search table for every row in the outer facets query. Signed-off-by: Fredrik Adelöw <freben@spotify.com> Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-catalog-backend': patch
|
||||
---
|
||||
|
||||
Fixed a performance regression in the `/entity-facets` endpoint when filters or permission conditions are applied, by routing the EXISTS-based filter through `final_entities` instead of correlating against the much larger `search` table.
|
||||
@@ -690,13 +690,24 @@ export class DefaultEntitiesCatalog implements EntitiesCatalog {
|
||||
.groupBy(['search.key', 'search.original_value']);
|
||||
|
||||
if (request.filter || request.query) {
|
||||
// Build a subquery that finds matching entity IDs via
|
||||
// final_entities, so that the EXISTS-based filters correlate
|
||||
// against one-row-per-entity rather than the much larger search
|
||||
// table. This keeps the facets aggregation fast even with many
|
||||
// filter clauses or permission conditions.
|
||||
const entityIdSubquery = this.database('final_entities')
|
||||
.select('final_entities.entity_id')
|
||||
.whereNotNull('final_entities.final_entity');
|
||||
|
||||
applyEntityFilterToQuery({
|
||||
filter: request.filter,
|
||||
query: request.query,
|
||||
targetQuery: query,
|
||||
onEntityIdField: 'search.entity_id',
|
||||
targetQuery: entityIdSubquery,
|
||||
onEntityIdField: 'final_entities.entity_id',
|
||||
knex: this.database,
|
||||
});
|
||||
|
||||
query.whereIn('search.entity_id', entityIdSubquery);
|
||||
}
|
||||
|
||||
const rows = await query;
|
||||
|
||||
Reference in New Issue
Block a user