From a8dc6daa38f1fdc09e477222451bd5a2612b59f5 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 10 Sep 2014 16:33:21 +1000 Subject: [PATCH] PERF: avoid OR in complex query 10x perf improvement on front page for sitepoint --- app/models/topic_tracking_state.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/models/topic_tracking_state.rb b/app/models/topic_tracking_state.rb index 2ed1bf5f0de..83caf3b84a1 100644 --- a/app/models/topic_tracking_state.rb +++ b/app/models/topic_tracking_state.rb @@ -144,7 +144,7 @@ class TopicTrackingState LEFT JOIN categories c ON c.id = topics.category_id WHERE u.id IN (:user_ids) AND topics.archetype <> 'private_message' AND - ((#{unread}) OR (#{new})) AND + (**COND**) AND (topics.visible OR u.admin OR u.moderator) AND topics.deleted_at IS NULL AND ( category_id IS NULL OR NOT c.read_restricted OR category_id IN ( @@ -163,11 +163,19 @@ SQL if topic_id sql << " AND topics.id = :topic_id" end - sql << " ORDER BY topics.bumped_at DESC LIMIT 500" + sql << " ORDER BY topics.bumped_at DESC LIMIT 250" + + sql = wrap(sql.sub("**COND**", new), "A") << " UNION ALL " << wrap(sql.sub("**COND**", unread),"B") SqlBuilder.new(sql) .map_exec(TopicTrackingState, user_ids: user_ids, topic_id: topic_id) end + private + + def self.wrap(query, name) + "SELECT * FROM (#{query}) #{name}" + end + end