From 3921691319ff80b03ed8927d56b078d3fffc936a Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Sun, 25 Aug 2024 20:43:22 -0700 Subject: [PATCH] Optimize SQL: CountLikesReceived --- pkg/models/like.go | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/pkg/models/like.go b/pkg/models/like.go index 62bd02b..da85568 100644 --- a/pkg/models/like.go +++ b/pkg/models/like.go @@ -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 }