From 8ee830e8258fe0ac1db01d7c64087b51abda9a65 Mon Sep 17 00:00:00 2001 From: Sam <sam.saffron@gmail.com> Date: Fri, 8 Jul 2016 12:54:03 +1000 Subject: [PATCH] PERF: improve performance of weekly job --- lib/score_calculator.rb | 54 +++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/lib/score_calculator.rb b/lib/score_calculator.rb index a9ee09758..681877bda 100644 --- a/lib/score_calculator.rb +++ b/lib/score_calculator.rb @@ -32,40 +32,58 @@ class ScoreCalculator private def update_posts_score(min_topic_age) + limit = 20000 + components = [] @weightings.each_key { |k| components << "COALESCE(#{k}, 0) * :#{k}" } components = components.join(" + ") - builder = SqlBuilder.new( - "UPDATE posts SET score = x.score - FROM (SELECT id, #{components} as score FROM posts) AS x - /*where*/" + builder = SqlBuilder.new <<SQL + UPDATE posts p + SET score = x.score + FROM ( + SELECT id, #{components} as score FROM posts + /*where*/ + limit #{limit} + ) AS x + WHERE x.id = p.id +SQL - ) - - builder.where("x.id = posts.id - AND (posts.score IS NULL OR x.score <> posts.score)", @weightings) + builder.where("score IS NULL OR score <> #{components}", @weightings) filter_topics(builder, min_topic_age) - builder.exec + while builder.exec.cmd_tuples == limit + end end def update_posts_rank(min_topic_age) + limit = 20000 - builder = SqlBuilder.new("UPDATE posts SET percent_rank = x.percent_rank - FROM (SELECT id, percent_rank() - OVER (PARTITION BY topic_id ORDER BY SCORE DESC) as percent_rank - FROM posts) AS x - /*where*/") - - builder.where("x.id = posts.id AND - (posts.percent_rank IS NULL OR x.percent_rank <> posts.percent_rank)") + builder = SqlBuilder.new <<SQL +UPDATE posts +SET percent_rank = X.percent_rank +FROM ( + SELECT posts.id, Y.percent_rank + FROM posts + JOIN ( + SELECT id, percent_rank() + OVER (PARTITION BY topic_id ORDER BY SCORE DESC) as percent_rank + FROM posts + ) Y ON Y.id = posts.id + /*where*/ + LIMIT #{limit} +) AS X +WHERE posts.id = X.id +SQL + builder.where("posts.percent_rank IS NULL OR Y.percent_rank <> posts.percent_rank") filter_topics(builder, min_topic_age) - builder.exec + while builder.exec.cmd_tuples == limit + end + end def update_topics_rank(min_topic_age)