أنا أراجع عملية إعادة تعبئة الشارات (badge backfill) الجارية هنا:
على وجه التحديد، يبدو أن الاستعلام التالي يحتوي على بعض المشاكل (انظر 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
هذا الاستعلام يقوم بعمل LEFT JOIN بحيث يتم إرجاع جميع النتائج من user_badges بغض النظر عما إذا كان هناك تطابق، لكن هذا الجزء يبدو مربكًا جدًا:
ON q.user_id = ub.user_id
...
AND q.user_id IS NULL
الاستعلام يربط الصفوف حيث يتطابق user_id، لكنه يتجاهل هذه الصفوف بعد ذلك عبر شرط WHERE، مما يجعل عملية الربط هناك غير مجدية تقريبًا. لذا أتساءل:
-
ما هو الغرض من وظيفة إعادة التعبئة؟ يبدو أنها تمسح الشارة التي تتم معالجتها بالكامل ثم يعيد بناءها دفعة واحدة. هل هذا ضروري؟
-
ما الفرق بين شارة تستهدف المنشورات وأخرى لا تفعل ذلك فيما يتعلق بهذه الوظيفة؟ مع وجود LEFT JOIN، هل يهم هذا الأمر حتى عند العثور على badge_id الصحيح للمسح وإعادة البناء؟