PERF: speed up query

This commit is contained in:
Sam 2015-04-16 17:29:18 +10:00
parent b903a83eea
commit 4387e05162
2 changed files with 29 additions and 9 deletions

View File

@ -82,18 +82,26 @@ class PostAction < ActiveRecord::Base
def self.lookup_for(user, topics, post_action_type_id)
return if topics.blank?
# in critical path 2x faster than AR
#
topic_ids = topics.map(&:id)
map = {}
PostAction.where(user_id: user.id, post_action_type_id: post_action_type_id, deleted_at: nil)
.references(:post)
.includes(:post)
.where('posts.topic_id in (?)', topics.map(&:id))
.order('posts.topic_id, posts.post_number')
.pluck('posts.topic_id, posts.post_number')
.each do |topic_id, post_number|
(map[topic_id] ||= []) << post_number
builder = SqlBuilder.new <<SQL
SELECT p.topic_id, p.post_number
FROM post_actions pa
JOIN posts p ON pa.post_id = p.id
WHERE p.deleted_at IS NULL AND pa.deleted_at IS NULL AND
pa.post_action_type_id = :post_action_type_id AND
pa.user_id = :user_id AND
p.topic_id IN (:topic_ids)
ORDER BY p.topic_id, p.post_number
SQL
builder.map_exec(OpenStruct, user_id: user.id, post_action_type_id: post_action_type_id, topic_ids: topic_ids).each do |row|
(map[row.topic_id] ||= []) << row.post_number
end
map
end

View File

@ -490,6 +490,18 @@ describe PostAction do
end
describe ".lookup_for" do
it "returns the correct map" do
user = Fabricate(:user)
post = Fabricate(:post)
post_action = PostAction.create(user_id: user.id, post_id: post.id, post_action_type_id: 1)
map = PostAction.lookup_for(user, [post.topic], post_action.post_action_type_id)
expect(map).to eq({post.topic_id => [post.post_number]})
end
end
describe ".add_moderator_post_if_needed" do
it "should not add a moderator post when it's disabled" do