From e2d566436f344408362c1679dd8b457693131752 Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Thu, 23 Apr 2026 14:10:48 -0600 Subject: [PATCH] add index for models --- ...0002_announcement_announcement_list_idx.py | 19 +++++++ announcement/models.py | 3 + .../0002_comment_comment_problem_time_idx.py | 21 +++++++ comment/models.py | 3 + ...rank_acm_rank_contest_user_idx_and_more.py | 23 ++++++++ contest/models.py | 2 + ...0002_message_message_recipient_time_idx.py | 20 +++++++ message/models.py | 3 + .../0007_problem_problem_visible_idx.py | 20 +++++++ problem/models.py | 1 + problemset/models.py | 57 +++++++++---------- .../0004_submission_problem_user_idx.py | 19 +++++++ submission/models.py | 3 + 13 files changed, 165 insertions(+), 29 deletions(-) create mode 100644 announcement/migrations/0002_announcement_announcement_list_idx.py create mode 100644 comment/migrations/0002_comment_comment_problem_time_idx.py create mode 100644 contest/migrations/0003_acmcontestrank_acm_rank_contest_user_idx_and_more.py create mode 100644 message/migrations/0002_message_message_recipient_time_idx.py create mode 100644 problem/migrations/0007_problem_problem_visible_idx.py create mode 100644 submission/migrations/0004_submission_problem_user_idx.py diff --git a/announcement/migrations/0002_announcement_announcement_list_idx.py b/announcement/migrations/0002_announcement_announcement_list_idx.py new file mode 100644 index 0000000..4aa1bc5 --- /dev/null +++ b/announcement/migrations/0002_announcement_announcement_list_idx.py @@ -0,0 +1,19 @@ +# Generated by Django 6.0 on 2026-04-23 20:07 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('announcement', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='announcement', + index=models.Index(fields=['visible', '-top', '-create_time'], name='announcement_list_idx'), + ), + ] diff --git a/announcement/models.py b/announcement/models.py index 68b9ede..c338b2b 100644 --- a/announcement/models.py +++ b/announcement/models.py @@ -18,3 +18,6 @@ class Announcement(models.Model): class Meta: db_table = "announcement" ordering = ("-top", "-create_time",) + indexes = [ + models.Index(fields=["visible", "-top", "-create_time"], name="announcement_list_idx"), + ] diff --git a/comment/migrations/0002_comment_comment_problem_time_idx.py b/comment/migrations/0002_comment_comment_problem_time_idx.py new file mode 100644 index 0000000..c2a4f7c --- /dev/null +++ b/comment/migrations/0002_comment_comment_problem_time_idx.py @@ -0,0 +1,21 @@ +# Generated by Django 6.0 on 2026-04-23 20:07 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('comment', '0001_initial'), + ('problem', '0007_problem_problem_visible_idx'), + ('submission', '0004_submission_problem_user_idx'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='comment', + index=models.Index(fields=['problem', 'create_time'], name='comment_problem_time_idx'), + ), + ] diff --git a/comment/models.py b/comment/models.py index 4ee58a1..f400d2d 100644 --- a/comment/models.py +++ b/comment/models.py @@ -40,5 +40,8 @@ class Comment(models.Model): class Meta: db_table = "comment" ordering = ("-create_time",) + indexes = [ + models.Index(fields=["problem", "create_time"], name="comment_problem_time_idx"), + ] diff --git a/contest/migrations/0003_acmcontestrank_acm_rank_contest_user_idx_and_more.py b/contest/migrations/0003_acmcontestrank_acm_rank_contest_user_idx_and_more.py new file mode 100644 index 0000000..bd520d0 --- /dev/null +++ b/contest/migrations/0003_acmcontestrank_acm_rank_contest_user_idx_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 6.0 on 2026-04-23 20:07 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contest', '0002_acmcontestrank_acm_rank_order_idx_and_more'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='acmcontestrank', + index=models.Index(fields=['contest', 'user'], name='acm_rank_contest_user_idx'), + ), + migrations.AddIndex( + model_name='oicontestrank', + index=models.Index(fields=['contest', 'user'], name='oi_rank_contest_user_idx'), + ), + ] diff --git a/contest/models.py b/contest/models.py index 0fd0f61..37b9c17 100644 --- a/contest/models.py +++ b/contest/models.py @@ -82,6 +82,7 @@ class ACMContestRank(AbstractContestRank): indexes = [ models.Index(fields=["contest", "accepted_number", "total_time"], name="acm_rank_order_idx"), + models.Index(fields=["contest", "user"], name="acm_rank_contest_user_idx"), ] @@ -96,6 +97,7 @@ class OIContestRank(AbstractContestRank): unique_together = (("user", "contest"),) indexes = [ models.Index(fields=["contest", "total_score"], name="oi_rank_order_idx"), + models.Index(fields=["contest", "user"], name="oi_rank_contest_user_idx"), ] diff --git a/message/migrations/0002_message_message_recipient_time_idx.py b/message/migrations/0002_message_message_recipient_time_idx.py new file mode 100644 index 0000000..bb987e7 --- /dev/null +++ b/message/migrations/0002_message_message_recipient_time_idx.py @@ -0,0 +1,20 @@ +# Generated by Django 6.0 on 2026-04-23 20:07 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('message', '0001_initial'), + ('submission', '0004_submission_problem_user_idx'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='message', + index=models.Index(fields=['recipient', 'create_time'], name='message_recipient_time_idx'), + ), + ] diff --git a/message/models.py b/message/models.py index a93b0ae..d46f7ca 100644 --- a/message/models.py +++ b/message/models.py @@ -17,3 +17,6 @@ class Message(models.Model): class Meta: db_table = "message" ordering = ("-create_time",) + indexes = [ + models.Index(fields=["recipient", "create_time"], name="message_recipient_time_idx"), + ] diff --git a/problem/migrations/0007_problem_problem_visible_idx.py b/problem/migrations/0007_problem_problem_visible_idx.py new file mode 100644 index 0000000..444a0a6 --- /dev/null +++ b/problem/migrations/0007_problem_problem_visible_idx.py @@ -0,0 +1,20 @@ +# Generated by Django 6.0 on 2026-04-23 20:07 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contest', '0003_acmcontestrank_acm_rank_contest_user_idx_and_more'), + ('problem', '0006_problem_problem_contest_visible_idx'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddIndex( + model_name='problem', + index=models.Index(fields=['visible'], name='problem_visible_idx'), + ), + ] diff --git a/problem/models.py b/problem/models.py index f32b336..bcdeae7 100644 --- a/problem/models.py +++ b/problem/models.py @@ -95,6 +95,7 @@ class Problem(models.Model): ordering = ("create_time",) indexes = [ models.Index(fields=["contest", "visible"], name="problem_contest_visible_idx"), + models.Index(fields=["visible"], name="problem_visible_idx"), ] def add_submission_number(self): diff --git a/problemset/models.py b/problemset/models.py index e0d5c1d..9f2392d 100644 --- a/problemset/models.py +++ b/problemset/models.py @@ -93,37 +93,36 @@ class ProblemSetBadge(models.Model): def recalculate_user_badges(self): """重新计算所有用户的徽章资格""" - # 获取所有已加入该题单的用户进度 + from django.db import transaction + user_progresses = ProblemSetProgress.objects.filter(problemset=self.problemset) - - # 删除该徽章的所有现有用户徽章记录 - UserBadge.objects.filter(badge=self).delete() - - # 重新评估每个用户的徽章资格 - for progress in user_progresses: - self._check_user_badge_eligibility(progress) - - def _check_user_badge_eligibility(self, progress): - """检查用户是否符合该徽章的条件""" - - # 检查是否已经拥有该徽章 - if UserBadge.objects.filter(user=progress.user, badge=self).exists(): - return False - - # 根据条件类型检查用户是否符合条件 + new_badges = [ + UserBadge(user=progress.user, badge=self) + for progress in user_progresses + if self._is_eligible(progress) + ] + with transaction.atomic(): + UserBadge.objects.filter(badge=self).delete() + if new_badges: + UserBadge.objects.bulk_create(new_badges) + + def _is_eligible(self, progress): + """判断用户进度是否满足该徽章条件(纯逻辑,不查数据库)""" if self.condition_type == "all_problems": - if progress.completed_problems_count == progress.total_problems_count: - UserBadge.objects.create(user=progress.user, badge=self) - return True - elif self.condition_type == "problem_count": - if progress.completed_problems_count >= self.condition_value: - UserBadge.objects.create(user=progress.user, badge=self) - return True - elif self.condition_type == "score": - if progress.total_score >= self.condition_value: - UserBadge.objects.create(user=progress.user, badge=self) - return True - + return progress.completed_problems_count == progress.total_problems_count + if self.condition_type == "problem_count": + return progress.completed_problems_count >= self.condition_value + if self.condition_type == "score": + return progress.total_score >= self.condition_value + return False + + def _check_user_badge_eligibility(self, progress): + """检查并授予单个用户的徽章(供外部单次调用)""" + if self._is_eligible(progress) and not UserBadge.objects.filter( + user=progress.user, badge=self + ).exists(): + UserBadge.objects.create(user=progress.user, badge=self) + return True return False diff --git a/submission/migrations/0004_submission_problem_user_idx.py b/submission/migrations/0004_submission_problem_user_idx.py new file mode 100644 index 0000000..bd66c10 --- /dev/null +++ b/submission/migrations/0004_submission_problem_user_idx.py @@ -0,0 +1,19 @@ +# Generated by Django 6.0 on 2026-04-23 20:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contest', '0003_acmcontestrank_acm_rank_contest_user_idx_and_more'), + ('problem', '0007_problem_problem_visible_idx'), + ('submission', '0003_add_contest_create_time_idx'), + ] + + operations = [ + migrations.AddIndex( + model_name='submission', + index=models.Index(fields=['problem_id', 'user_id'], name='problem_user_idx'), + ), + ] diff --git a/submission/models.py b/submission/models.py index 05dbf13..82238b5 100644 --- a/submission/models.py +++ b/submission/models.py @@ -64,6 +64,9 @@ class Submission(models.Model): models.Index( fields=["contest_id", "-create_time"], name="contest_create_time_idx" ), + models.Index( + fields=["problem_id", "user_id"], name="problem_user_idx" + ), ] def __str__(self):