Estou analisando o processo de preenchimento de badges que está ocorrendo aqui:
Em particular, a seguinte consulta parece apresentar alguns problemas (veja Long-Running Sidekiq Jobs)
sql = <<~SQL
DELETE FROM user_badges
WHERE id IN (
SELECT ub.id
FROM user_badges ub
LEFT JOIN (
#{badge.query}
) q ON q.user_id = ub.user_id
#{post_clause}
WHERE ub.badge_id = :id AND q.user_id IS NULL
)
SQL
Esta consulta realiza um LEFT JOIN, de modo que todos os resultados de user_badges serão retornados, independentemente de haver correspondência, mas esta parte parece muito confusa:
ON q.user_id = ub.user_id
...
AND q.user_id IS NULL
A consulta faz o join em linhas onde o user_id corresponde, mas depois descarta essas linhas por meio da cláusula WHERE, tornando o join ali praticamente inútil. Então, estou me perguntando:
-
Qual é o propósito da função de preenchimento? Parece que ela apaga completamente o badge sendo processado e depois o reconstrói tudo de uma vez. Isso é necessário?
-
Qual é a diferença entre um badge que tem como alvo posts e um que não tem, em relação a esta função? Com um LEFT JOIN, isso realmente importa ao encontrar o badge_id correto para apagar e reconstruir?