From 297967ebd7590f145b0ae67412f4b7388eb9a846 Mon Sep 17 00:00:00 2001 From: Seth Call Date: Thu, 12 Oct 2017 11:13:54 -0500 Subject: [PATCH] optimize the heck out of some terrible queries --- db/up/sms_index_optimize.sql | 8 +++ ruby/lib/jam_ruby/models/music_session.rb | 60 +++++++++++-------- .../jam_ruby/models/music_session_spec.rb | 9 +++ 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/db/up/sms_index_optimize.sql b/db/up/sms_index_optimize.sql index 65c53b771..13b0bb204 100644 --- a/db/up/sms_index_optimize.sql +++ b/db/up/sms_index_optimize.sql @@ -194,6 +194,14 @@ $$ LANGUAGE plpgsql; -- CREATE INDEX index_invitations_on_music_session_id ON invitations USING btree(music_session_id); -- select sms_index_test('062deeba-b917-46e2-bfa3-e829405ca602'::varchar, 26880045373::bigint, 18.911563873291::integer, 'any'::varchar, false::boolean) +-- CREATE INDEX index_affiliate_traffic_totals_on_day ON affiliate_traffic_totals USING btree(day); +-- CREATE INDEX index_affiliate_traffic_totals_on_affiliate_partner_id ON affiliate_traffic_totals USING btree(affiliate_partner_id); +-- CREATE INDEX index_users_on_affiliate_referral_id ON users USING btree(affiliate_referral_id); +-- CREATE INDEX index_users_on_created_at ON users USING btree(created_at); +-- CREATE INDEX index_share_tokens_on_shareable_id ON share_tokens USING btree(shareable_id); +-- CREATE INDEX index_music_sessions_on_create_type ON music_sessions USING btree(create_type); +-- CREATE INDEX index_music_sessions_on_scheduled_start ON music_sessions USING btree(scheduled_start); +-- CREATE INDEX index_music_sessions_on_canceled ON music_sessions USING btree(canceled); -- update music_sessions set canceled = true WHERE (scheduled_start IS NULL OR scheduled_start > (NOW() - (interval '15 minute'))) AND canceled = FALSE AND description != 'Jam Track Session' AND id NOT IN (SELECT id FROM active_music_sessions) AND id NOT IN (select distinct on(name, user_id) id FROM music_sessions WHERE (scheduled_start IS NULL OR scheduled_start > (NOW() - (interval '15 minute'))) AND canceled = FALSE AND description != 'Jam Track Session' AND id NOT IN (SELECT id FROM active_music_sessions) order by name, user_id); diff --git a/ruby/lib/jam_ruby/models/music_session.rb b/ruby/lib/jam_ruby/models/music_session.rb index 4f965a4a6..2ed761e4e 100644 --- a/ruby/lib/jam_ruby/models/music_session.rb +++ b/ruby/lib/jam_ruby/models/music_session.rb @@ -547,8 +547,21 @@ module JamRuby # let session be restarted for up to 2 hours after finishing session_finished = "(music_sessions.session_removed_at > NOW() - '2 hour'::INTERVAL)" - query = MusicSession.joins( + query = MusicSession.select('distinct music_sessions.*') + query = query.joins( %Q{ + LEFT OUTER JOIN + rsvp_slots + ON + music_sessions.id = rsvp_slots.music_session_id + LEFT OUTER JOIN + rsvp_requests_rsvp_slots + ON + rsvp_requests_rsvp_slots.rsvp_slot_id = rsvp_slots.id + LEFT OUTER JOIN + rsvp_requests + ON rsvp_requests.id = rsvp_requests_rsvp_slots.rsvp_request_id + LEFT OUTER JOIN invitations ON @@ -558,16 +571,8 @@ module JamRuby query = query.where("music_sessions.canceled = FALSE") query = query.where('music_sessions.fan_access = TRUE or music_sessions.musician_access = TRUE') if only_public #query = query.where("music_sessions.user_id = '#{user.id}' OR invitations.id IS NOT NULL") - query = query.where("music_sessions.id in ( - select distinct(rs.music_session_id) - from rsvp_slots rs - where rs.id in ( - select rrrs.rsvp_slot_id - from rsvp_requests rr - inner join rsvp_requests_rsvp_slots rrrs on rr.id = rrrs.rsvp_request_id - where rr.user_id = '#{user.id}'AND rrrs.chosen = true - ) - ) OR invitations.id IS NOT NULL OR music_sessions.user_id = '#{user.id}'") + query = query.where("(rsvp_requests.id IS NOT NULL AND rsvp_requests_rsvp_slots.id IS NOT NULL AND rsvp_requests.user_id = '#{user.id}' AND rsvp_requests_rsvp_slots.chosen = true) OR (invitations.id IS NOT NULL) OR (music_sessions.user_id = '#{user.id}') ") + query = query.where("music_sessions.scheduled_start IS NULL OR #{session_not_started} OR #{session_finished} OR #{session_started_not_finished}") query = query.where("music_sessions.create_type IS NULL OR (music_sessions.create_type != '#{CREATE_TYPE_QUICK_START}' AND music_sessions.create_type != '#{CREATE_TYPE_QUICK_PUBLIC}')") query = query.order("music_sessions.scheduled_start ASC") @@ -578,22 +583,29 @@ module JamRuby # if only_approved is set, then only return sessions where the current user has been chosen def self.scheduled_rsvp(user, only_approved = false) - filter_approved = only_approved ? 'AND rrrs.chosen = true' : '' + filter_approved = only_approved ? 'AND rsvp_requests_rsvp_slots.chosen = true' : '' - MusicSession.where(%Q{music_sessions.canceled = FALSE AND + query = MusicSession.joins( + %Q{ + INNER JOIN + rsvp_slots + ON + music_sessions.id = rsvp_slots.music_session_id + INNER JOIN + rsvp_requests_rsvp_slots + ON + rsvp_requests_rsvp_slots.rsvp_slot_id = rsvp_slots.id + INNER JOIN + rsvp_requests + ON rsvp_requests.id = rsvp_requests_rsvp_slots.rsvp_request_id + } + ) + + query = query.where(%Q{music_sessions.canceled = FALSE AND (music_sessions.create_type is NULL OR (music_sessions.create_type != '#{CREATE_TYPE_QUICK_START}' AND music_sessions.create_type != '#{CREATE_TYPE_QUICK_PUBLIC}')) AND - (music_sessions.scheduled_start is NULL OR music_sessions.scheduled_start > NOW() - '4 hour'::INTERVAL) AND - music_sessions.id in ( - select distinct(rs.music_session_id) - from rsvp_slots rs - where rs.id in ( - select rrrs.rsvp_slot_id - from rsvp_requests rr - inner join rsvp_requests_rsvp_slots rrrs on rr.id = rrrs.rsvp_request_id - where rr.user_id = '#{user.id}' #{filter_approved} - ) - )} + (music_sessions.scheduled_start is NULL OR music_sessions.scheduled_start > NOW() - '4 hour'::INTERVAL) AND rsvp_requests.user_id = '#{user.id}' #{filter_approved}} ).order(:scheduled_start) + query end def self.create user, options diff --git a/ruby/spec/jam_ruby/models/music_session_spec.rb b/ruby/spec/jam_ruby/models/music_session_spec.rb index 9a1de6bd5..502533e4f 100644 --- a/ruby/spec/jam_ruby/models/music_session_spec.rb +++ b/ruby/spec/jam_ruby/models/music_session_spec.rb @@ -378,6 +378,11 @@ describe MusicSession do sessions = MusicSession.scheduled(approved_rsvps[0]) + sessions.each do |session| + puts session.name + puts session.description + end + sessions.length.should == 1 sessions = MusicSession.scheduled(approved_rsvps[1]) @@ -829,7 +834,11 @@ describe MusicSession do let(:creator_1) { FactoryGirl.create(:user) } let!(:music_session_1) { FactoryGirl.create(:music_session, :creator => creator_1, description: "Bunny Jumps", :create_type => MusicSession::CREATE_TYPE_IMMEDIATE ) } + let!(:music_session_2) { FactoryGirl.create(:music_session, :creator => FactoryGirl.create(:user), description: "Bunny Jumps", :create_type => MusicSession::CREATE_TYPE_IMMEDIATE ) } + before(:each) { + music_session_2.touch + } it "lists one" do MusicSession.scheduled_rsvp(creator_1).should == [music_session_1] end