Langlaufende Sidekiq-Jobs

Dennoch muss die Unterabfrage ausgeführt werden, um die Ränge für jedes Thema in der gesamten posts-Tabelle zu berechnen, unabhängig davon, wie viele Ränge tatsächlich aktualisiert werden.

Diese Unterabfrage benötigt etwa 40 Sekunden, und sie befindet sich in einer geschachtelten Schleife, die für den Join ausgeführt werden muss, bevor wir überhaupt die WHERE-Klausel erreichen. Das scheint der Grund dafür zu sein, dass die Abfragekosten explodieren.

SELECT id, percent_rank()                                                     
    OVER (PARTITION BY topic_id ORDER BY SCORE DESC) as percent_rank 
FROM posts
1 „Gefällt mir“

Ich habe mir den Code angesehen und verstehe es jetzt. Diese Abfrage wird wiederholt ausgeführt, bis alle Beiträge, deren Rang aktualisiert werden muss, abgearbeitet sind. Als ich also die SQL-Prozesse beobachtet habe, habe ich im Laufe der Stunden viele verschiedene Ausführungen dieser Abfrage gesehen, während eine abgeschlossen wurde und die nächste begann.

Allerdings scheint das LIMIT die Komplexität der Abfrage nicht wirklich allzu sehr zu verringern. Tatsächlich habe ich festgestellt, dass sich der Abfrageplan erheblich verbessert, wenn ich das Limit auf 200.000 erhöhe.
Bei 20.000 sehe ich eine riesige verschachtelte Schleife mit Kosten von fast 200 Millionen:

-> Nested Loop (cost=6033694.44..190270554.32 rows=26680560 width=16)

Wenn ich das Limit einfach auf 200.000 erhöhe, ergibt sich dieser Abfrageplan, der viel übersichtlicher aussieht:

                                                            QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
 Update on posts  (cost=7334394.89..8873863.82 rows=200000 width=833)
   ->  Nested Loop  (cost=7334394.89..8873863.82 rows=200000 width=833)
         ->  Subquery Scan on x  (cost=7334394.45..7370147.82 rows=200000 width=48)
               ->  Limit  (cost=7334394.45..7368147.82 rows=200000 width=12)
                     ->  Hash Join  (cost=7334394.45..11837188.36 rows=26680560 width=12)
                           Hash Cond: (posts_1.id = y.id)
                           Join Filter: ((posts_1.percent_rank IS NULL) OR (y.percent_rank <> posts_1.percent_rank))
                           ->  Hash Join  (cost=35403.20..2845221.73 rows=26703700 width=12)
                                 Hash Cond: (posts_1.topic_id = topics.id)
                                 ->  Seq Scan on posts posts_1  (cost=0.00..2739721.00 rows=26703700 width=16)
                                 ->  Hash  (cost=23918.11..23918.11 rows=918807 width=4)
                                       ->  Index Only Scan using topics_pkey on topics  (cost=0.42..23918.11 rows=918807 width=4)
                           ->  Hash  (cost=6834805.00..6834805.00 rows=26703700 width=12)
                                 ->  Subquery Scan on y  (cost=6033694.00..6834805.00 rows=26703700 width=12)
                                       ->  WindowAgg  (cost=6033694.00..6567768.00 rows=26703700 width=24)
                                             ->  Sort  (cost=6033694.00..6100453.25 rows=26703700 width=16)
                                                   Sort Key: posts_2.topic_id, posts_2.score DESC
                                                   ->  Seq Scan on posts posts_2  (cost=0.00..2739721.00 rows=26703700 width=16)
         ->  Index Scan using posts_pkey on posts  (cost=0.44..7.52 rows=1 width=789)
               Index Cond: (id = x.id)
 JIT:
   Functions: 30
   Options: Inlining true, Optimization true, Expressions true, Deforming true
(23 rows)

Ich frage mich, was diesen Wechsel verursacht. Es könnte sich lohnen, dies zumindest nach einem großen Import wie dem, den wir durchgeführt haben, zu erhöhen, während der Rückstand abgearbeitet wird.

2 „Gefällt mir“