PERF: Speed up moving posts on large databases

Old exection plan:
```
Delete on post_replies pr  (cost=6.59..20462.62 rows=2254 width=24) (actual time=2.580..2.580 rows=0 loops=1)
  ->  Nested Loop  (cost=6.59..20462.62 rows=2254 width=24) (actual time=0.086..2.557 rows=4 loops=1)
        Join Filter: (p.topic_id <> r.topic_id)
        Rows Removed by Join Filter: 328
        ->  Nested Loop  (cost=6.16..16845.77 rows=2254 width=26) (actual time=0.020..1.886 rows=332 loops=1)
              ->  Nested Loop  (cost=5.74..13257.09 rows=2254 width=20) (actual time=0.016..1.361 rows=332 loops=1)
                    ->  Seq Scan on moved_posts mp  (cost=0.00..19.70 rows=970 width=10) (actual time=0.002..0.028 rows=263 loops=1)
                    ->  Bitmap Heap Scan on post_replies pr  (cost=5.74..13.63 rows=2 width=14) (actual time=0.004..0.005 rows=1 loops=263)
                          Recheck Cond: ((reply_post_id = mp.old_post_id) OR (post_id = mp.old_post_id))
                          Heap Blocks: exact=278
                          ->  BitmapOr  (cost=5.74..5.74 rows=2 width=0) (actual time=0.004..0.004 rows=0 loops=263)
                                ->  Bitmap Index Scan on index_post_replies_on_reply_post_id  (cost=0.00..2.87 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=263)
                                      Index Cond: (reply_post_id = mp.old_post_id)
                                ->  Bitmap Index Scan on index_post_replies_on_post_id_and_reply_post_id  (cost=0.00..2.87 rows=1 width=0) (actual time=0.002..0.002 rows=1 loops=263)
                                      Index Cond: (post_id = mp.old_post_id)
              ->  Index Scan using posts_pkey on posts p  (cost=0.42..1.59 rows=1 width=14) (actual time=0.001..0.001 rows=1 loops=332)
                    Index Cond: (id = pr.post_id)
        ->  Index Scan using posts_pkey on posts r  (cost=0.42..1.59 rows=1 width=14) (actual time=0.001..0.002 rows=1 loops=332)
              Index Cond: (id = pr.reply_post_id)
Planning Time: 0.305 ms
Execution Time: 2.600 ms
```

New execution plan:
```
Delete on post_replies pr  (cost=15.34..6538275.37 rows=364157 width=12) (actual time=1.961..1.961 rows=0 loops=1)
  ->  Nested Loop  (cost=15.34..6538275.37 rows=364157 width=12) (actual time=0.048..1.827 rows=187 loops=1)
        ->  Seq Scan on moved_posts mp  (cost=0.00..19.70 rows=970 width=10) (actual time=0.004..0.029 rows=188 loops=1)
        ->  Bitmap Heap Scan on post_replies pr  (cost=15.34..6736.72 rows=375 width=14) (actual time=0.009..0.009 rows=1 loops=188)
              Recheck Cond: ((reply_post_id = mp.old_post_id) OR (post_id = mp.old_post_id))
              Filter: ((SubPlan 1) <> (SubPlan 2))
              Heap Blocks: exact=187
              ->  BitmapOr  (cost=15.34..15.34 rows=377 width=0) (actual time=0.003..0.003 rows=0 loops=188)
                    ->  Bitmap Index Scan on index_post_replies_on_reply_post_id  (cost=0.00..4.33 rows=1 width=0) (actual time=0.001..0.001 rows=1 loops=188)
                          Index Cond: (reply_post_id = mp.old_post_id)
                    ->  Bitmap Index Scan on index_post_replies_on_post_id_and_reply_post_id  (cost=0.00..10.82 rows=376 width=0) (actual time=0.001..0.001 rows=0 loops=188)
                          Index Cond: (post_id = mp.old_post_id)
              SubPlan 1
                ->  Index Scan using posts_pkey on posts p  (cost=0.43..8.45 rows=1 width=4) (actual time=0.002..0.002 rows=1 loops=187)
                      Index Cond: (id = pr.post_id)
              SubPlan 2
                ->  Index Scan using posts_pkey on posts r  (cost=0.43..8.45 rows=1 width=4) (actual time=0.002..0.003 rows=1 loops=187)
                      Index Cond: (id = pr.reply_post_id)
Planning Time: 0.136 ms
Execution Time: 1.990 ms
```
This commit is contained in:
Gerhard Schlager 2020-02-04 00:26:13 +01:00
parent e84d88ddea
commit 71849242fa
1 changed files with 4 additions and 4 deletions

View File

@ -282,10 +282,10 @@ class PostMover
def delete_post_replies
DB.exec <<~SQL
DELETE
FROM post_replies pr USING moved_posts mp, posts p, posts r
WHERE (pr.reply_post_id = mp.old_post_id OR pr.post_id = mp.old_post_id) AND
p.id = pr.post_id AND r.id = pr.reply_post_id AND p.topic_id <> r.topic_id
DELETE FROM post_replies pr USING moved_posts mp
WHERE (SELECT topic_id FROM posts WHERE id = pr.post_id) <>
(SELECT topic_id FROM posts WHERE id = pr.reply_post_id)
AND (pr.reply_post_id = mp.old_post_id OR pr.post_id = mp.old_post_id)
SQL
end