mirror of
https://github.com/go-gitea/gitea.git
synced 2026-11-02 13:44:16 +09:00
Backport #40114 by @silverwind The repository issue and pull request lists filter `access` by `repo_id`, which no index covers, so every load scans the whole table. Issue counts on larger repositories merge three single-column indices, and the API pull request list loads the latest reviews with `id IN (SELECT max(id) ... GROUP BY ...)`, which MySQL runs as a scan of every review, about 1.1s on https://gitea.com/api/v1/repos/gitea/gitea-mcp/pulls?limit=1. - Index `access.repo_id` - Index `team_repo.repo_id` - Replace the single `repo_id`, `is_closed` and `is_pull` indices with one `issue` index on `(repo_id, is_closed, is_pull)` - Join the latest review ids instead of `id IN (subquery)` Median times in ms on MySQL 8.4 with tables sized like gitea.com (1M access rows, 500k issues, 200k reviews), for a copy of https://gitea.com/gitea/gitea-mcp and a repository with 9.7k issues: | Page | Before | After | |---|---|---| | `/{owner}/{repo}/issues` | 107 | 40 | | `/{owner}/{repo}/pulls` | 106 | 32 | | `/{owner}/{repo}/pulls?state=closed` | 153 | 35 | | `/{owner}/{repo}/issues/{index}` | 141 | 60 | | `/{owner}/{repo}/issues`, 9.7k issues | 303 | 53 | | `/api/v1/repos/{owner}/{repo}/pulls?limit=50` | 180 | 46 | | `/api/v1/repos/{owner}/{repo}/pulls?limit=1` | 137 | 16 | | `/api/v1/repos/{owner}/{repo}/issues`, 9.7k issues | 248 | 43 | Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
6 files changed
+10
-12
No files matched your search
@@ -335,8 +335,8 @@ func (prs PullRequestList) LoadReviews(ctx context.Context) (ReviewList, error)
|
||||
"reviewer_team_id": 0,
|
||||
}).
|
||||
GroupBy("issue_id, reviewer_id")
|
||||
// Get latest review of each reviewer, sorted in order they were made
|
||||
if err := db.GetEngine(ctx).In("id", subQuery).OrderBy("review.updated_unix ASC").Find(&reviews); err != nil {
|
||||
// Get latest review of each reviewer, sorted in order they were made. Joined because MySQL scans all reviews for "id IN (subquery)", xorm aliases the subquery "review".
|
||||
if err := db.GetEngine(ctx).Table("review").Alias("latest").Join("INNER", subQuery, "latest.id = review.id").OrderBy("latest.updated_unix ASC").Find(&reviews); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -350,7 +350,7 @@ func (prs PullRequestList) LoadReviews(ctx context.Context) (ReviewList, error)
|
||||
"reviewer_team_id": 0,
|
||||
}).
|
||||
GroupBy("issue_id, reviewer_team_id")
|
||||
if err := db.GetEngine(ctx).In("id", subQueryTeam).OrderBy("review.updated_unix ASC").Find(&teamReviewRequests); err != nil {
|
||||
if err := db.GetEngine(ctx).Table("review").Alias("latest").Join("INNER", subQueryTeam, "latest.id = review.id").OrderBy("latest.updated_unix ASC").Find(&teamReviewRequests); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user