mirror of
https://github.com/discourse/discourse.git
synced 2025-03-20 22:58:32 +08:00
FIX: Optimize move to dismiss_new_topics migration (#12041)
This migration is quite heavy because of join to all potential topics which should be `dismissed` for each user. To make it a little bit more efficient I did two things: - move conditions to join so it should use fewer rows - do that in batches - 1000 users at the time
This commit is contained in:
parent
395a903cf6
commit
7426764af4
@ -2,35 +2,40 @@
|
|||||||
|
|
||||||
class MoveNewSinceToNewTable < ActiveRecord::Migration[6.0]
|
class MoveNewSinceToNewTable < ActiveRecord::Migration[6.0]
|
||||||
def up
|
def up
|
||||||
sql = <<~SQL
|
User.find_in_batches do |users|
|
||||||
|
sql = <<~SQL
|
||||||
INSERT INTO dismissed_topic_users (user_id, topic_id, created_at)
|
INSERT INTO dismissed_topic_users (user_id, topic_id, created_at)
|
||||||
SELECT users.id, topics.id, user_stats.new_since
|
SELECT users.id, topics.id, user_stats.new_since
|
||||||
FROM user_stats
|
FROM user_stats
|
||||||
JOIN users ON users.id = user_stats.user_id
|
JOIN users ON users.id = user_stats.user_id
|
||||||
JOIN user_options ON user_options.user_id = users.id
|
JOIN user_options ON user_options.user_id = users.id
|
||||||
LEFT JOIN topics ON topics.created_at <= user_stats.new_since
|
LEFT JOIN topics ON topics.created_at <= user_stats.new_since
|
||||||
|
AND topics.archetype <> :private_message
|
||||||
|
AND topics.created_at >= GREATEST(CASE
|
||||||
|
WHEN COALESCE(user_options.new_topic_duration_minutes, :default_duration) = :always THEN users.created_at
|
||||||
|
WHEN COALESCE(user_options.new_topic_duration_minutes, :default_duration) = :last_visit THEN COALESCE(users.previous_visit_at,users.created_at)
|
||||||
|
ELSE (:now::timestamp - INTERVAL '1 MINUTE' * COALESCE(user_options.new_topic_duration_minutes, :default_duration))
|
||||||
|
END, :min_date)
|
||||||
LEFT JOIN topic_users ON topics.id = topic_users.topic_id AND users.id = topic_users.user_id
|
LEFT JOIN topic_users ON topics.id = topic_users.topic_id AND users.id = topic_users.user_id
|
||||||
LEFT JOIN dismissed_topic_users ON dismissed_topic_users.topic_id = topics.id AND users.id = dismissed_topic_users.user_id
|
LEFT JOIN dismissed_topic_users ON dismissed_topic_users.topic_id = topics.id AND users.id = dismissed_topic_users.user_id
|
||||||
WHERE user_stats.new_since IS NOT NULL
|
WHERE user_stats.new_since IS NOT NULL
|
||||||
AND topic_users.id IS NULL
|
AND topic_users.id IS NULL
|
||||||
|
AND topics.id IS NOT NULL
|
||||||
AND dismissed_topic_users.id IS NULL
|
AND dismissed_topic_users.id IS NULL
|
||||||
AND topics.archetype <> :private_message
|
AND users.id IN (:user_ids)
|
||||||
AND topics.created_at >= GREATEST(CASE
|
|
||||||
WHEN COALESCE(user_options.new_topic_duration_minutes, :default_duration) = :always THEN users.created_at
|
|
||||||
WHEN COALESCE(user_options.new_topic_duration_minutes, :default_duration) = :last_visit THEN COALESCE(users.previous_visit_at,users.created_at)
|
|
||||||
ELSE (:now::timestamp - INTERVAL '1 MINUTE' * COALESCE(user_options.new_topic_duration_minutes, :default_duration))
|
|
||||||
END, :min_date)
|
|
||||||
ORDER BY topics.created_at DESC
|
ORDER BY topics.created_at DESC
|
||||||
LIMIT :max_new_topics
|
LIMIT :max_new_topics
|
||||||
SQL
|
SQL
|
||||||
DB.exec(sql,
|
DB.exec(sql,
|
||||||
now: DateTime.now,
|
now: DateTime.now,
|
||||||
last_visit: User::NewTopicDuration::LAST_VISIT,
|
last_visit: User::NewTopicDuration::LAST_VISIT,
|
||||||
always: User::NewTopicDuration::ALWAYS,
|
always: User::NewTopicDuration::ALWAYS,
|
||||||
default_duration: SiteSetting.default_other_new_topic_duration_minutes,
|
default_duration: SiteSetting.default_other_new_topic_duration_minutes,
|
||||||
min_date: Time.at(SiteSetting.min_new_topics_time).to_datetime,
|
min_date: Time.at(SiteSetting.min_new_topics_time).to_datetime,
|
||||||
private_message: Archetype.private_message,
|
private_message: Archetype.private_message,
|
||||||
max_new_topics: SiteSetting.max_new_topics)
|
user_ids: users.map(&:id),
|
||||||
|
max_new_topics: SiteSetting.max_new_topics)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
|
Loading…
x
Reference in New Issue
Block a user