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:
@@ -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