diff options
author | Takeshi Umeda <noel.yoshiba@gmail.com> | 2020-09-23 23:01:54 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-23 16:01:54 +0200 |
commit | b655a7f88f653e143d85e1d01bfedde42dc6d9e4 (patch) | |
tree | f2f5400265c66eaa7ed07221b23b9df8e48a5e2a | |
parent | e39d97f7008499bbf91bb0fb3ae2f794c50f40fc (diff) |
Fix a slow query for TagFeed (#14861)
* Fix a slow query for TagFeed * rename tags to tag_ids
-rw-r--r-- | app/models/status.rb | 10 | ||||
-rw-r--r-- | app/models/tag_feed.rb | 2 |
2 files changed, 6 insertions, 6 deletions
diff --git a/app/models/status.rb b/app/models/status.rb index c6e16ff75..96d90e1c2 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -89,19 +89,19 @@ class Status < ApplicationRecord scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') } scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') } scope :with_public_visibility, -> { where(visibility: :public) } - scope :tagged_with, ->(tag) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag }) } + scope :tagged_with, ->(tag_ids) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag_ids }) } scope :in_chosen_languages, ->(account) { where(language: nil).or where(language: account.chosen_languages) } scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) } scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) } scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) } scope :not_domain_blocked_by_account, ->(account) { account.excluded_from_timeline_domains.blank? ? left_outer_joins(:account) : left_outer_joins(:account).where('accounts.domain IS NULL OR accounts.domain NOT IN (?)', account.excluded_from_timeline_domains) } - scope :tagged_with_all, ->(tags) { - Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id| + scope :tagged_with_all, ->(tag_ids) { + Array(tag_ids).reduce(self) do |result, id| result.joins("INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}") end } - scope :tagged_with_none, ->(tags) { - Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id| + scope :tagged_with_none, ->(tag_ids) { + Array(tag_ids).reduce(self) do |result, id| result.joins("LEFT OUTER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}") .where("t#{id}.tag_id IS NULL") end diff --git a/app/models/tag_feed.rb b/app/models/tag_feed.rb index 50634fe83..9a16ffc82 100644 --- a/app/models/tag_feed.rb +++ b/app/models/tag_feed.rb @@ -52,6 +52,6 @@ class TagFeed < PublicFeed end def tags_for(names) - Tag.matching_name(Array(names).take(LIMIT_PER_MODE)) if names.present? + Tag.matching_name(Array(names).take(LIMIT_PER_MODE)).pluck(:id) if names.present? end end |