diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2024-09-03 03:05:09 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-02 19:05:09 +0000 |
commit | 85b1f3080c74681b6fca45625687606490408172 (patch) | |
tree | e949093c49f30904f6aa503e3a94a8fa4fb3225c | |
parent | 83f37f630246e381eefd650fc2d4b1f3976ea882 (diff) | |
download | gitea-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.go | 47 |
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 { |