Optimize SQL: CountLikesReceived

This commit is contained in:
Noah Petherbridge 2024-08-25 20:43:22 -07:00
parent e0e98d8df6
commit 3921691319

View File

@ -77,20 +77,34 @@ func CountLikesGiven(user *User) int64 {
// CountLikesReceived by a user.
func CountLikesReceived(user *User) int64 {
var count int64
DB.Model(&Like{}).Joins(
"LEFT OUTER JOIN photos ON (likes.table_name = 'photos' AND likes.table_id = photos.id)",
).Joins(
"LEFT OUTER JOIN users ON (likes.table_name = 'users' AND likes.table_id = users.id)",
).Joins(
"LEFT OUTER JOIN comments ON (likes.table_name = 'comments' AND likes.table_id = comments.id)",
).Where(`
(likes.table_name = 'photos' AND photos.user_id = ?)
OR
(likes.table_name = 'users' AND likes.table_id = ?)
OR
(likes.table_name = 'comments' AND comments.user_id = ?)`,
user.ID, user.ID, user.ID,
).Count(&count)
// Do a UNION query as it's more efficient than joining Likes to all the other tables.
result := DB.Raw(`
SELECT sum(c) FROM (
SELECT count(*) AS c
FROM likes
WHERE likes.table_name = 'users' AND likes.table_id = ?
UNION
SELECT count(*) AS c
FROM likes
JOIN photos ON (likes.table_name='photos' AND likes.table_id=photos.id)
WHERE photos.user_id = ?
UNION
SELECT count(*) AS c
FROM likes
JOIN comments ON (likes.table_name = 'comments' AND likes.table_id=comments.id)
WHERE comments.user_id = ?
) AS c
`, user.ID, user.ID, user.ID).Scan(&count)
if result.Error != nil {
log.Error("CountLikesReceived: %s", result.Error)
}
return count
}