Fix n+1 query issue on dependencies controllers
What does this MR do and why?
The Dependency List UI uses has_dependency_paths returned from /dependencies (or /dependencies/location in case of Group Dependency List) to decide whether or not to display View Dependency Paths. This value was previously calculated by making n calls to the DB for n occurrences. This MR fixes that to make only 1 query.
- Moves
has_dependency_pathsfrom LocationEntity to be directly underDependencyEntity- Makes more sense that dependency has dependency paths
- Also fixes n+1 query issues on
Sbom::Exporters::CsvServiceandSbom::Exporters::JsonArrayService, since they don't use the has_dependency_paths attribute at all. - Only the dependencies controllers use the has_dependency_paths attr.
- Updates UI to match the above change.
- Updates specs.
DB changes -
Project Dependency list query -
Before
SELECT "sbom_occurrences".*
FROM "sbom_occurrences"
LEFT OUTER JOIN "sbom_sources" ON "sbom_sources"."id" = "sbom_occurrences"."source_id"
WHERE "sbom_occurrences"."project_id" = 1
AND "sbom_occurrences"."traversal_ids" = '{1}'
AND "sbom_occurrences"."archived" = FALSE
AND "sbom_occurrences"."project_id" = 1
AND ("sbom_sources"."source_type" IN (0,
1)
OR "sbom_sources"."source_type" IS NULL)
ORDER BY "sbom_occurrences"."highest_severity" DESC NULLS LAST
LIMIT 20
OFFSET 0
plan - https://console.postgres.ai/gitlab/gitlab-production-sec/sessions/41737/commands/128096
After
SELECT "sbom_occurrences".*,
EXISTS (
(SELECT 1
FROM "sbom_graph_paths"
WHERE "sbom_graph_paths"."descendant_id" = "sbom_occurrences"."id"
LIMIT 1)) AS has_dependency_paths
FROM "sbom_occurrences"
LEFT OUTER JOIN "sbom_sources" ON "sbom_sources"."id" = "sbom_occurrences"."source_id"
WHERE "sbom_occurrences"."project_id" = 1
AND "sbom_occurrences"."traversal_ids" = '{1}'
AND "sbom_occurrences"."archived" = FALSE
AND "sbom_occurrences"."project_id" = 1
AND ("sbom_sources"."source_type" IN (0,
1)
OR "sbom_sources"."source_type" IS NULL)
ORDER BY "sbom_occurrences"."highest_severity" DESC NULLS LAST
LIMIT 20
OFFSET 0;
plan - https://console.postgres.ai/gitlab/gitlab-production-sec/sessions/41737/commands/128095
/dependencies/locations call on Group Dependency list page -
Before
SELECT "sbom_occurrences".*
FROM "sbom_occurrences"
WHERE (sbom_occurrences.traversal_ids >= '{1}'
AND '{2}' > sbom_occurrences.traversal_ids)
AND "sbom_occurrences"."component_version_id" = 1
LIMIT 50;
plan - https://console.postgres.ai/gitlab/gitlab-production-sec/sessions/41737/commands/128099
After
SELECT "sbom_occurrences".*,
EXISTS (
(SELECT 1
FROM "sbom_graph_paths"
WHERE "sbom_graph_paths"."descendant_id" = "sbom_occurrences"."id"
LIMIT 1)) AS has_dependency_paths
FROM "sbom_occurrences"
WHERE (sbom_occurrences.traversal_ids >= '{1}'
AND '{2}' > sbom_occurrences.traversal_ids)
AND "sbom_occurrences"."component_version_id" = 1
LIMIT 50;
plan - https://console.postgres.ai/gitlab/gitlab-production-sec/sessions/41737/commands/128100
References
Screenshots or screen recordings
| Before | After |
|---|---|
How to set up and validate locally
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.