Skip to content

[PR #8135/b3c4388d backport][3.119] Improve the performance of the latest publication lookup when serving content from a repository-backed distribution. - #8138

Open
patchback[bot] wants to merge 1 commit into
3.119from
patchback/backports/3.119/b3c4388d1ce6f6654f22d7cf9c22b65027f0f867/pr-8135
Open

patchback[bot] wants to merge 1 commit into
3.119from
patchback/backports/3.119/b3c4388d1ce6f6654f22d7cf9c22b65027f0f867/pr-8135

Conversation

@patchback

@patchback patchback Bot commented Sep 25, 2026

Copy link
Copy Markdown

This is a backport of PR #8135 as merged into main (b3c4388).

Distribution.get_repository_publication_and_version() resolves the newest publication for a repository-backed distribution with repository_version__in=repository.versions.all(). Django renders that as a subquery joined on pulp_id, which hides repository_id from the planner. It cannot use the (repository_id, number) unique index and instead scans the global index on number, filtering each row by repository.

Since number is a per-repository counter and that index is global, the work is set by the total number of repository versions across all repositories rather than by the size of the repository being served. On an installation with a large number of repository versions this scans a substantial portion of core_repositoryversion to return a single row, and every repository degrades as any of them grow.

Filtering with repository_version__repository selects the same rows but keeps repository_id visible, so the planner uses the (repository_id, number) index and the lookup becomes a short index scan.

The same query was also hydrating repository_version.content_ids through select_related, which nothing on this path reads; it is now deferred.

closes #1995

Assisted-by: Claude Opus 5 (GitHub Copilot)

📜 Checklist

  • Commits are cleanly separated with meaningful messages (simple features and bug fixes should be squashed to one commit)
  • A changelog entry or entries has been added for any significant changes
  • Follows the Pulp policy on AI Usage
  • (For new features) - User documentation and test coverage has been added

See: Pull Request Walkthrough

Distribution.get_repository_publication_and_version() resolves the newest
publication for a repository-backed distribution with
repository_version__in=repository.versions.all(). Django renders that as a
subquery joined on pulp_id, which hides repository_id from the planner. It
cannot use the (repository_id, number) unique index and instead scans the
global index on number, filtering each row by repository.

Since number is a per-repository counter and that index is global, the work
is set by the total number of repository versions across all repositories
rather than by the size of the repository being served. On an installation
with a large number of repository versions this scans a substantial portion
of core_repositoryversion to return a single row, and every repository
degrades as any of them grow.

Filtering with repository_version__repository selects the same rows but keeps
repository_id visible, so the planner uses the (repository_id, number) index
and the lookup becomes a short index scan.

The same query also pulled repository_version.content_ids in via
select_related. Nothing on this path reads it, and it holds every content
unit UUID in the version, so defer it.

closes #1995

Assisted-by: Claude Opus 5 (GitHub Copilot)
(cherry picked from commit b3c4388)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant