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) def self.lookup_for(user, topics, post_action_type_id)
return if topics.blank? return if topics.blank?
# in critical path 2x faster than AR
#
topic_ids = topics.map(&:id)
map = {} map = {}
PostAction.where(user_id: user.id, post_action_type_id: post_action_type_id, deleted_at: nil) builder = SqlBuilder.new <<SQL
.references(:post) SELECT p.topic_id, p.post_number
.includes(:post) FROM post_actions pa
.where('posts.topic_id in (?)', topics.map(&:id)) JOIN posts p ON pa.post_id = p.id
.order('posts.topic_id, posts.post_number') WHERE p.deleted_at IS NULL AND pa.deleted_at IS NULL AND
.pluck('posts.topic_id, posts.post_number') pa.post_action_type_id = :post_action_type_id AND
.each do |topic_id, post_number| pa.user_id = :user_id AND
(map[topic_id] ||= []) << post_number 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 end
map map
end end

View File

@ -490,6 +490,18 @@ describe PostAction do
end 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 describe ".add_moderator_post_if_needed" do
it "should not add a moderator post when it's disabled" do it "should not add a moderator post when it's disabled" do