From 4777ba210f4c78e12d3700a0f4c45343b5459fd5 Mon Sep 17 00:00:00 2001
From: Giteabot <teabot@gitea.io>
Date: Sun, 21 Apr 2024 08:50:50 +0800
Subject: [PATCH] Fix package list performance (#30520) (#30616)

Backport #30520 by @KN4CK3R

Fixes #28255

The new query uses the id field to sort by "newer". This most not be
correct (usually it is) but it's faster (see #28255).
If someone has a better idea, please propose changes.

Co-authored-by: KN4CK3R <admin@oldschoolhack.me>
(cherry picked from commit ea2ea8ef28b6a2207ec00bafaf42d428612d69eb)
---
 models/packages/package_version.go | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/models/packages/package_version.go b/models/packages/package_version.go
index 505dbaa0a5..278e8e3a86 100644
--- a/models/packages/package_version.go
+++ b/models/packages/package_version.go
@@ -287,9 +287,10 @@ func (opts *PackageSearchOptions) configureOrderBy(e db.Engine) {
 // SearchVersions gets all versions of packages matching the search options
 func SearchVersions(ctx context.Context, opts *PackageSearchOptions) ([]*PackageVersion, int64, error) {
 	sess := db.GetEngine(ctx).
-		Where(opts.ToConds()).
+		Select("package_version.*").
 		Table("package_version").
-		Join("INNER", "package", "package.id = package_version.package_id")
+		Join("INNER", "package", "package.id = package_version.package_id").
+		Where(opts.ToConds())
 
 	opts.configureOrderBy(sess)
 
@@ -304,19 +305,18 @@ func SearchVersions(ctx context.Context, opts *PackageSearchOptions) ([]*Package
 
 // SearchLatestVersions gets the latest version of every package matching the search options
 func SearchLatestVersions(ctx context.Context, opts *PackageSearchOptions) ([]*PackageVersion, int64, error) {
-	cond := opts.ToConds().
-		And(builder.Expr("pv2.id IS NULL"))
-
-	joinCond := builder.Expr("package_version.package_id = pv2.package_id AND (package_version.created_unix < pv2.created_unix OR (package_version.created_unix = pv2.created_unix AND package_version.id < pv2.id))")
-	if opts.IsInternal.Has() {
-		joinCond = joinCond.And(builder.Eq{"pv2.is_internal": opts.IsInternal.Value()})
-	}
+	in := builder.
+		Select("MAX(package_version.id)").
+		From("package_version").
+		InnerJoin("package", "package.id = package_version.package_id").
+		Where(opts.ToConds()).
+		GroupBy("package_version.package_id")
 
 	sess := db.GetEngine(ctx).
+		Select("package_version.*").
 		Table("package_version").
-		Join("LEFT", "package_version pv2", joinCond).
 		Join("INNER", "package", "package.id = package_version.package_id").
-		Where(cond)
+		Where(builder.In("package_version.id", in))
 
 	opts.configureOrderBy(sess)