Fix a slow query for TagFeed (#14861)

* Fix a slow query for TagFeed

* rename tags to tag_ids
main
Takeshi Umeda 2020-09-23 23:01:54 +09:00 committed by GitHub
parent e39d97f700
commit b655a7f88f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 6 deletions

View File

@ -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_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 :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
scope :with_public_visibility, -> { where(visibility: :public) } 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 :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 :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 :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_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 :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) { scope :tagged_with_all, ->(tag_ids) {
Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id| 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}") result.joins("INNER JOIN statuses_tags t#{id} ON t#{id}.status_id = statuses.id AND t#{id}.tag_id = #{id}")
end end
} }
scope :tagged_with_none, ->(tags) { scope :tagged_with_none, ->(tag_ids) {
Array(tags).map(&:id).map(&:to_i).reduce(self) do |result, id| 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}") 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") .where("t#{id}.tag_id IS NULL")
end end

View File

@ -52,6 +52,6 @@ class TagFeed < PublicFeed
end end
def tags_for(names) 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
end end