From c3b7120042af5fb2345b6efd315954deb698b4c0 Mon Sep 17 00:00:00 2001
From: Giteabot <teabot@gitea.io>
Date: Thu, 21 Sep 2023 11:42:34 +0800
Subject: [PATCH] Add index to `issue_user.issue_id` (#27154) (#27158)

Backport #27154 by @JakobDev

This fixes a performance bottleneck. It was discovered by Codeberg.
Every where query on that table (which has grown big over time) uses
this column, but there is no index on it.

See this part of the log which was posted on Matrix:
```
2023/09/10 00:52:01 ...rs/web/repo/issue.go:1446:ViewIssue() [W] [Slow SQL Query] UPDATE `issue_user` SET is_read=? WHERE uid=? AND issue_id=? [true x y] - 51.395434887s
2023/09/10 00:52:01 ...rs/web/repo/issue.go:1447:ViewIssue() [E] ReadBy: Error 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
2023/09/10 00:52:01 ...eb/routing/logger.go:102:func1() [I] router: completed GET /Codeberg/Community/issues/1201 for [::ffff:xxx]:0, 500 Internal Server Error in 52384.2ms @ repo/issue.go:1256(repo.ViewIssue)
```

Co-authored-by: JakobDev <jakobdev@gmx.de>
---
 models/issues/issue_user.go     |  2 +-
 models/migrations/migrations.go |  2 ++
 models/migrations/v1_21/v277.go | 16 ++++++++++++++++
 3 files changed, 19 insertions(+), 1 deletion(-)
 create mode 100644 models/migrations/v1_21/v277.go

diff --git a/models/issues/issue_user.go b/models/issues/issue_user.go
index d053b1d543..24bb74648d 100644
--- a/models/issues/issue_user.go
+++ b/models/issues/issue_user.go
@@ -15,7 +15,7 @@ import (
 type IssueUser struct {
 	ID          int64 `xorm:"pk autoincr"`
 	UID         int64 `xorm:"INDEX"` // User ID.
-	IssueID     int64
+	IssueID     int64 `xorm:"INDEX"`
 	IsRead      bool
 	IsMentioned bool
 }
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 3524077ea4..38fff37bed 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -534,6 +534,8 @@ var migrations = []Migration{
 	NewMigration("Add ScheduleID for ActionRun", v1_21.AddScheduleIDForActionRun),
 	// v276 -> v277
 	NewMigration("Add RemoteAddress to mirrors", v1_21.AddRemoteAddressToMirrors),
+	// v277 -> v278
+	NewMigration("Add Index to issue_user.issue_id", v1_21.AddIndexToIssueUserIssueID),
 }
 
 // GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v1_21/v277.go b/models/migrations/v1_21/v277.go
new file mode 100644
index 0000000000..12529160b7
--- /dev/null
+++ b/models/migrations/v1_21/v277.go
@@ -0,0 +1,16 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_21 //nolint
+
+import (
+	"xorm.io/xorm"
+)
+
+func AddIndexToIssueUserIssueID(x *xorm.Engine) error {
+	type IssueUser struct {
+		IssueID int64 `xorm:"INDEX"`
+	}
+
+	return x.Sync(new(IssueUser))
+}