aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2024-09-03 03:05:09 +0800
committerGitHub <noreply@github.com>2024-09-02 19:05:09 +0000
commit85b1f3080c74681b6fca45625687606490408172 (patch)
treee949093c49f30904f6aa503e3a94a8fa4fb3225c
parent83f37f630246e381eefd650fc2d4b1f3976ea882 (diff)
downloadgitea-85b1f3080c74681b6fca45625687606490408172.tar.gz
gitea-85b1f3080c74681b6fca45625687606490408172.zip
Improve get feed with pagination (#31821)
Fix #31752 @somera --------- Co-authored-by: delvh <dev.lh@web.de>
-rw-r--r--models/activities/action.go47
1 files changed, 38 insertions, 9 deletions
diff --git a/models/activities/action.go b/models/activities/action.go
index d23f2bd986..532667d495 100644
--- a/models/activities/action.go
+++ b/models/activities/action.go
@@ -450,17 +450,46 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, int64, err
return nil, 0, err
}
- sess := db.GetEngine(ctx).Where(cond).
- Select("`action`.*"). // this line will avoid select other joined table's columns
- Join("INNER", "repository", "`repository`.id = `action`.repo_id")
+ actions := make([]*Action, 0, opts.PageSize)
+ var count int64
- opts.SetDefaultValues()
- sess = db.SetSessionPagination(sess, &opts)
+ if opts.Page < 10 { // TODO: why it's 10 but other values? It's an experience value.
+ sess := db.GetEngine(ctx).Where(cond).
+ Select("`action`.*"). // this line will avoid select other joined table's columns
+ Join("INNER", "repository", "`repository`.id = `action`.repo_id")
- actions := make([]*Action, 0, opts.PageSize)
- count, err := sess.Desc("`action`.created_unix").FindAndCount(&actions)
- if err != nil {
- return nil, 0, fmt.Errorf("FindAndCount: %w", err)
+ opts.SetDefaultValues()
+ sess = db.SetSessionPagination(sess, &opts)
+
+ count, err = sess.Desc("`action`.created_unix").FindAndCount(&actions)
+ if err != nil {
+ return nil, 0, fmt.Errorf("FindAndCount: %w", err)
+ }
+ } else {
+ // First, only query which IDs are necessary, and only then query all actions to speed up the overall query
+ sess := db.GetEngine(ctx).Where(cond).
+ Select("`action`.id").
+ Join("INNER", "repository", "`repository`.id = `action`.repo_id")
+
+ opts.SetDefaultValues()
+ sess = db.SetSessionPagination(sess, &opts)
+
+ actionIDs := make([]int64, 0, opts.PageSize)
+ if err := sess.Table("action").Desc("`action`.created_unix").Find(&actionIDs); err != nil {
+ return nil, 0, fmt.Errorf("Find(actionsIDs): %w", err)
+ }
+
+ count, err = db.GetEngine(ctx).Where(cond).
+ Table("action").
+ Cols("`action`.id").
+ Join("INNER", "repository", "`repository`.id = `action`.repo_id").Count()
+ if err != nil {
+ return nil, 0, fmt.Errorf("Count: %w", err)
+ }
+
+ if err := db.GetEngine(ctx).In("`action`.id", actionIDs).Desc("`action`.created_unix").Find(&actions); err != nil {
+ return nil, 0, fmt.Errorf("Find: %w", err)
+ }
}
if err := ActionList(actions).LoadAttributes(ctx); err != nil {