PERF: Faster moving of read state

This should improve the performance of moving the read state of lots of posts to a new/existing topic.
This commit is contained in:
Gerhard Schlager 2019-10-11 17:31:20 +02:00
parent 086b46051c
commit f1742617fb
1 changed files with 19 additions and 14 deletions

View File

@ -333,32 +333,37 @@ class PostMover
WHERE p.topic_id = tu.topic_id WHERE p.topic_id = tu.topic_id
AND p.user_id = tu.user_id AND p.user_id = tu.user_id
) AS posted, ) AS posted,
MAX(lr.new_post_number) AS last_read_post_number, (
MAX(hs.new_post_number) AS highest_seen_post_number, SELECT MAX(lr.new_post_number)
MAX(le.new_post_number) AS last_emailed_post_number, FROM moved_posts lr
WHERE lr.old_topic_id = tu.topic_id
AND lr.old_post_number <= tu.last_read_post_number
) AS last_read_post_number,
(
SELECT MAX(hs.new_post_number)
FROM moved_posts hs
WHERE hs.old_topic_id = tu.topic_id
AND hs.old_post_number <= tu.highest_seen_post_number
) AS highest_seen_post_number,
(
SELECT MAX(le.new_post_number)
FROM moved_posts le
WHERE le.old_topic_id = tu.topic_id
AND le.old_post_number <= tu.last_emailed_post_number
) AS last_emailed_post_number,
GREATEST(tu.first_visited_at, t.created_at) AS first_visited_at, GREATEST(tu.first_visited_at, t.created_at) AS first_visited_at,
GREATEST(tu.last_visited_at, t.created_at) AS last_visited_at, GREATEST(tu.last_visited_at, t.created_at) AS last_visited_at,
tu.notification_level, tu.notification_level,
tu.notifications_changed_at, tu.notifications_changed_at,
tu.notifications_reason_id tu.notifications_reason_id
FROM topic_users tu FROM topic_users tu
JOIN topics t JOIN topics t ON (t.id = :new_topic_id)
ON (t.id = :new_topic_id)
LEFT OUTER JOIN moved_posts lr
ON (lr.old_topic_id = tu.topic_id AND lr.old_post_number <= tu.last_read_post_number)
LEFT OUTER JOIN moved_posts hs
ON (hs.old_topic_id = tu.topic_id AND hs.old_post_number <= tu.highest_seen_post_number)
LEFT OUTER JOIN moved_posts le
ON (le.old_topic_id = tu.topic_id AND le.old_post_number <= tu.last_emailed_post_number)
WHERE tu.topic_id = :old_topic_id WHERE tu.topic_id = :old_topic_id
AND GREATEST( AND GREATEST(
tu.last_read_post_number, tu.last_read_post_number,
tu.highest_seen_post_number, tu.highest_seen_post_number,
tu.last_emailed_post_number tu.last_emailed_post_number
) >= (SELECT MIN(old_post_number) FROM moved_posts) ) >= (SELECT MIN(old_post_number) FROM moved_posts)
GROUP BY tu.topic_id, tu.user_id, tu.first_visited_at, tu.last_visited_at, t.created_at, tu.notification_level,
tu.notifications_changed_at,
tu.notifications_reason_id
ON CONFLICT (topic_id, user_id) DO UPDATE ON CONFLICT (topic_id, user_id) DO UPDATE
SET posted = excluded.posted, SET posted = excluded.posted,
last_read_post_number = CASE last_read_post_number = CASE