Estoy revisando el proceso de relleno de insignias que se está ejecutando aquí:
En particular, la siguiente consulta parece tener algunos problemas (ver 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 un LEFT JOIN, por lo que se devolverán todos los resultados de user_badges independientemente de si hay una coincidencia, pero esta parte parece muy confusa:
ON q.user_id = ub.user_id
...
AND q.user_id IS NULL
La consulta une las filas donde el user_id coincide, pero luego descarta esas filas mediante la cláusula WHERE, lo que hace que la unión sea casi inútil. Por lo tanto, me pregunto:
-
¿Cuál es el propósito de la función de relleno? Parece borrar completamente la insignia que se está procesando y luego reconstruirla por completo de una sola vez. ¿Es esto necesario?
-
¿Cuál es la diferencia entre una insignia que apunta a publicaciones y una que no, en relación con esta función? Con un LEFT JOIN, ¿realmente importa esto al encontrar el badge_id correcto para borrar y reconstruir?