perf: Various performance regression fixes (#38078)

Fixes five N+1 / O(n) query patterns found across common user paths.
Each uses a bulk query that already existed elsewhere in the codebase.

| Location | Problem | Introduced in |
| -------------------------------- |
-------------------------------------------------------------------------------------------------------------------------------
| ------------- |
| `IssueList.LoadIsRead` | `.In("issue_id")` missing its arg — xorm
generates `WHERE 0=1`, so `IsRead` is **never** set; every issue always
appears unread | #29515 |
| `ParseCommitsWithStatus` | `GetLatestCommitStatus` called once per
commit (O(n) queries on commit list / PR commits tab) | #33605 |
| `getReleaseInfos` (release list) | `GetLatestCommitStatus` called once
per release for CI badges | #29149 |
| User milestone dashboard | O(n×m) nested loop matching milestones to
repos | #26300 |
| `findCodeComments` (PR diff) | `LoadResolveDoer` + `LoadReactions`
called per inline comment — up to ~150 queries on a PR with 50 comments
| #20821 |

---------

Co-authored-by: Lauris B <lauris@nix.lv>
This commit is contained in:
bircni
2026-06-21 16:34:07 +02:00
committed by GitHub
parent ceec230fc0
commit 180af33f86
7 changed files with 135 additions and 32 deletions

View File

@@ -101,6 +101,19 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
canReadActions := ctx.Repo.Permission.CanRead(unit.TypeActions)
// Bulk-load commit statuses for all releases in one query.
var commitStatusMap map[string][]*git_model.CommitStatus
if canReadActions && len(releases) > 0 {
shas := make([]string, 0, len(releases))
for _, r := range releases {
shas = append(shas, r.Sha1)
}
commitStatusMap, err = git_model.GetLatestCommitStatusForRepoCommitIDs(ctx, ctx.Repo.Repository.ID, shas)
if err != nil {
return nil, err
}
}
releaseInfos := make([]*ReleaseInfo, 0, len(releases))
for _, r := range releases {
if r.Publisher, ok = cacheUsers[r.PublisherID]; !ok {
@@ -130,11 +143,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
}
if canReadActions {
statuses, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptionsAll)
if err != nil {
return nil, err
}
statuses := commitStatusMap[r.Sha1]
info.CommitStatus = git_model.CalcCommitStatus(statuses)
info.CommitStatuses = statuses
}

View File

@@ -242,13 +242,13 @@ func Milestones(ctx *context.Context) {
}
sort.Sort(showRepos)
repoByID := make(map[int64]*repo_model.Repository, len(showRepos))
for _, repo := range showRepos {
repoByID[repo.ID] = repo
}
for i := 0; i < len(milestones); {
for _, repo := range showRepos {
if milestones[i].RepoID == repo.ID {
milestones[i].Repo = repo
break
}
}
milestones[i].Repo = repoByID[milestones[i].RepoID]
if milestones[i].Repo == nil {
log.Warn("Cannot find milestone %d 's repository %d", milestones[i].ID, milestones[i].RepoID)
milestones = append(milestones[:i], milestones[i+1:]...)