PERF: Cache user badge count in user_stats table (#8610)

This means that we no longer need to run a `count()` on the user_badges table when serializing a user
This commit is contained in:
David Taylor
2019-12-30 11:19:59 +00:00
committed by GitHub
parent c15d702ae6
commit 9348d2cfdf
6 changed files with 99 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ class UserStat < ActiveRecord::Base
def self.ensure_consistency!(last_seen = 1.hour.ago)
reset_bounce_scores
update_distinct_badge_count
update_view_counts(last_seen)
update_first_unread(last_seen)
end
@@ -126,6 +127,29 @@ class UserStat < ActiveRecord::Base
SQL
end
def self.update_distinct_badge_count(user_id = nil)
sql = <<~SQL
UPDATE user_stats
SET distinct_badge_count = x.distinct_badge_count
FROM (
SELECT users.id user_id, COUNT(distinct user_badges.badge_id) distinct_badge_count
FROM users
LEFT JOIN user_badges ON user_badges.user_id = users.id
AND (user_badges.badge_id IN (SELECT id FROM badges WHERE enabled))
GROUP BY users.id
) x
WHERE user_stats.user_id = x.user_id AND user_stats.distinct_badge_count <> x.distinct_badge_count
SQL
sql = sql + " AND user_stats.user_id = #{user_id.to_i}" if user_id
DB.exec sql
end
def update_distinct_badge_count
self.class.update_distinct_badge_count(self.user_id)
end
# topic_reply_count is a count of posts in other users' topics
def update_topic_reply_count
self.topic_reply_count = Topic