From 6e42e3b1eca73c306db1580719a3a1bfb715f6d8 Mon Sep 17 00:00:00 2001 From: rubic0n Date: Sun, 28 Feb 2021 19:45:44 -0600 Subject: [PATCH 1/2] Improve home feed query --- app/models/home_feed.rb | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/app/models/home_feed.rb b/app/models/home_feed.rb index cd3f4f5b..b2917298 100644 --- a/app/models/home_feed.rb +++ b/app/models/home_feed.rb @@ -16,11 +16,7 @@ class HomeFeed < Feed private def from_database(limit, max_id, since_id, min_id) - pagination_max = "" - pagination_min = "" - pagination_max = "and s.id < #{max_id}" unless max_id.nil? - pagination_min = "and s.id > #{min_id}" unless min_id.nil? - Status.find_by_sql " + Status.find_by_sql([<<-SQL, { id: @id, limit: limit, min_id: min_id, max_id: max_id }]) with cte as ( select @@ -36,14 +32,14 @@ class HomeFeed < Feed where s.created_at > NOW() - INTERVAL '7 days' and s.reply is false - and (exists(select ff.target_account_id from follows ff where ff.account_id = #{@id} and ff.target_account_id = s.account_id) - or s.account_id = #{@id}) - and not exists(select mm.target_account_id from mutes mm where mm.account_id = #{@id} and mm.target_account_id in (s.account_id, r.account_id)) - and not exists(select bb.target_account_id from blocks bb where bb.account_id = #{@id} and bb.target_account_id in (s.account_id, r.account_id)) - #{pagination_max} - #{pagination_min} + and (exists(select ff.target_account_id from follows ff where ff.account_id = :id and ff.target_account_id = s.account_id) + or s.account_id = :id) + and not exists(select mm.target_account_id from mutes mm where mm.account_id = :id and mm.target_account_id in (s.account_id, r.account_id)) + and not exists(select bb.target_account_id from blocks bb where bb.account_id = :id and bb.target_account_id in (s.account_id, r.account_id)) + and (:max_id is null or s.id < :max_id) + and (:min_id is null or s.id > :min_id) order by s.created_at desc - limit #{limit} + limit :limit ) sid ) select @@ -53,6 +49,6 @@ class HomeFeed < Feed where cte.rn_dupe = 1 or cte.reblog_of_id is null order by so.created_at desc - " + SQL end end From 3b704cec7dbe96339de0e1a7c77dbc1f676c9e21 Mon Sep 17 00:00:00 2001 From: rubic0n Date: Sun, 28 Feb 2021 19:50:01 -0600 Subject: [PATCH 2/2] Use a constant --- app/models/home_feed.rb | 75 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/app/models/home_feed.rb b/app/models/home_feed.rb index b2917298..0abfa30d 100644 --- a/app/models/home_feed.rb +++ b/app/models/home_feed.rb @@ -1,6 +1,41 @@ # frozen_string_literal: true class HomeFeed < Feed + QUERY = <<-SQL + with cte as + ( + select + row_number() over (partition by sid.reblog_of_id order by sid.id desc) as rn_dupe, + sid.* + FROM + (select + s.id, + s.reblog_of_id + from statuses s + left join statuses r + on s.reblog_of_id = r.id + where + s.created_at > NOW() - INTERVAL '7 days' + and s.reply is false + and (exists(select ff.target_account_id from follows ff where ff.account_id = :id and ff.target_account_id = s.account_id) + or s.account_id = :id) + and not exists(select mm.target_account_id from mutes mm where mm.account_id = :id and mm.target_account_id in (s.account_id, r.account_id)) + and not exists(select bb.target_account_id from blocks bb where bb.account_id = :id and bb.target_account_id in (s.account_id, r.account_id)) + and (:max_id is null or s.id < :max_id) + and (:min_id is null or s.id > :min_id) + order by s.created_at desc + limit :limit + ) sid + ) + select + so.* + from cte + inner join statuses so on cte.id = so.id + where + cte.rn_dupe = 1 or cte.reblog_of_id is null + order by so.created_at desc + SQL + def initialize(account) @type = :home @id = account.id @@ -9,46 +44,8 @@ class HomeFeed < Feed def get(limit = 20, max_id = nil, since_id = nil, min_id = nil) ActiveRecord::Base.connected_to(role: :reading) do - from_database(limit, max_id, since_id, min_id) + Status.find_by_sql([QUERY, { id: @id, limit: limit, min_id: min_id, max_id: max_id }]) end end - private - - def from_database(limit, max_id, since_id, min_id) - Status.find_by_sql([<<-SQL, { id: @id, limit: limit, min_id: min_id, max_id: max_id }]) - with cte as - ( - select - row_number() over (partition by sid.reblog_of_id order by sid.id desc) as rn_dupe, - sid.* - FROM - (select - s.id, - s.reblog_of_id - from statuses s - left join statuses r - on s.reblog_of_id = r.id - where - s.created_at > NOW() - INTERVAL '7 days' - and s.reply is false - and (exists(select ff.target_account_id from follows ff where ff.account_id = :id and ff.target_account_id = s.account_id) - or s.account_id = :id) - and not exists(select mm.target_account_id from mutes mm where mm.account_id = :id and mm.target_account_id in (s.account_id, r.account_id)) - and not exists(select bb.target_account_id from blocks bb where bb.account_id = :id and bb.target_account_id in (s.account_id, r.account_id)) - and (:max_id is null or s.id < :max_id) - and (:min_id is null or s.id > :min_id) - order by s.created_at desc - limit :limit - ) sid - ) - select - so.* - from cte - inner join statuses so on cte.id = so.id - where - cte.rn_dupe = 1 or cte.reblog_of_id is null - order by so.created_at desc - SQL - end end