/moderator/dashboard: optimize sql queries

* Converts queries to use active record instead of raw sql. This ensures
  that user objects are loaded by rails in the join, so that we
  don't have to issue `User.find` calls to load users one-by-one.

* Use `.includes` to preload associations used in the view, to avoid
  additional N+1 query problems (primarily, calls to link_to_user
  also causing users to be loaded one-by-one).
This commit is contained in:
evazion
2017-03-18 18:21:13 -05:00
parent b3e3012a9c
commit d1d0fe9bc5
10 changed files with 62 additions and 144 deletions

View File

@@ -1,28 +1,16 @@
module Moderator
module Dashboard
module Queries
class WikiPage
attr_reader :user, :count
class WikiPage < ::Struct.new(:user, :count)
def self.all(min_date, max_level)
sql = <<-EOS
SELECT wiki_page_versions.updater_id, count(*)
FROM wiki_page_versions
JOIN users ON users.id = wiki_page_versions.updater_id
WHERE
wiki_page_versions.created_at > ?
AND users.level <= ?
GROUP BY wiki_page_versions.updater_id
ORDER BY count(*) DESC
LIMIT 10
EOS
ActiveRecord::Base.select_all_sql(sql, min_date, max_level).map {|x| new(x)}
end
def initialize(hash)
@user = ::User.find(hash["updater_id"])
@count = hash["count"]
::WikiPageVersion.joins(:updater)
.where("wiki_page_versions.created_at > ?", min_date)
.where("users.level <= ?", max_level)
.group(:updater)
.order("count(*) desc")
.limit(10)
.count
.map { |user, count| new(user, count) }
end
end
end