From 4ef642b3004fad659869e3ed052b0d343206eea3 Mon Sep 17 00:00:00 2001 From: Sam Date: Fri, 19 Feb 2021 11:35:52 +1100 Subject: [PATCH] FIX: optimise MoveNewSinceToTable (#12136) * FIX: optimise MoveNewSinceToTable Avoids shuffling all ids around to the app (only use min / max) Ensure the query for boundaries is ordered by user_id --- ...10208022739_move_new_since_to_new_table.rb | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/db/post_migrate/20210208022739_move_new_since_to_new_table.rb b/db/post_migrate/20210208022739_move_new_since_to_new_table.rb index a0efe780e30..a23bac97794 100644 --- a/db/post_migrate/20210208022739_move_new_since_to_new_table.rb +++ b/db/post_migrate/20210208022739_move_new_since_to_new_table.rb @@ -7,8 +7,20 @@ class MoveNewSinceToNewTable < ActiveRecord::Migration[6.0] def up offset = 0 loop do - user_stat_user_ids = DB.query("SELECT user_id FROM user_stats LIMIT #{BATCH_SIZE} OFFSET :offset", offset: offset).map(&:user_id) - break if user_stat_user_ids.count.zero? + min_id, max_id = DB.query_single(<<~SQL, offset: offset, batch_size: BATCH_SIZE) + SELECT min(user_id), max(user_id) + FROM ( + SELECT user_id + FROM user_stats + ORDER BY user_id + LIMIT :batch_size + OFFSET :offset + ) X + SQL + + # will return nil + break if !min_id + sql = <<~SQL INSERT INTO dismissed_topic_users (user_id, topic_id, created_at) SELECT users.id, topics.id, user_stats.new_since @@ -26,13 +38,15 @@ class MoveNewSinceToNewTable < ActiveRecord::Migration[6.0] 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 WHERE user_stats.new_since IS NOT NULL - AND user_stats.user_id IN (:user_stat_user_ids) + AND user_stats.user_id >= :min_id + AND user_stats.user_id <= :max_id AND topic_users.last_read_post_number IS NULL AND topics.id IS NOT NULL AND dismissed_topic_users.id IS NULL ORDER BY topics.created_at DESC ON CONFLICT DO NOTHING SQL + DB.exec(sql, now: DateTime.now, last_visit: User::NewTopicDuration::LAST_VISIT, @@ -40,9 +54,12 @@ class MoveNewSinceToNewTable < ActiveRecord::Migration[6.0] default_duration: SiteSetting.default_other_new_topic_duration_minutes, min_date: Time.at(SiteSetting.min_new_topics_time).to_datetime, private_message: Archetype.private_message, - user_stat_user_ids: user_stat_user_ids, + min_id: min_id, + max_id: max_id, max_new_topics: SiteSetting.max_new_topics) - offset = offset + BATCH_SIZE + + offset += BATCH_SIZE + end end