Skip to content

Commit 128c452

Browse files
authored
perf: Optimize flag comparison database queries
1 parent 13ff78c commit 128c452

File tree

1 file changed

+47
-25
lines changed

1 file changed

+47
-25
lines changed

apps/worker/tasks/compute_comparison.py

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -135,35 +135,57 @@ def create_or_update_flag_comparisons(
135135
comparison_proxy: ComparisonProxy,
136136
):
137137
repository_id = comparison.compare_commit.repository.repoid
138-
for flag_name in head_report_flags.keys():
139-
totals = self.get_flag_comparison_totals(flag_name, comparison_proxy)
140-
repositoryflag = (
141-
db_session.query(RepositoryFlag)
142-
.filter_by(
143-
flag_name=flag_name,
144-
repository_id=repository_id,
145-
)
146-
.first()
138+
flag_names = list(head_report_flags.keys())
139+
140+
# Batch-fetch all existing RepositoryFlag records for this repo and flag set
141+
existing_repo_flags = (
142+
db_session.query(RepositoryFlag)
143+
.filter(
144+
RepositoryFlag.repository_id == repository_id,
145+
RepositoryFlag.flag_name.in_(flag_names),
147146
)
148-
if not repositoryflag:
149-
log.warning(
150-
"Repository flag not found for flag. Created repository flag.",
151-
extra={"repoid": repository_id, "flag_name": flag_name},
152-
)
153-
repositoryflag = RepositoryFlag(
147+
.all()
148+
)
149+
repo_flags_by_name = {rf.flag_name: rf for rf in existing_repo_flags}
150+
151+
# Bulk-create any missing RepositoryFlag records in one flush
152+
missing_flag_names = [
153+
name for name in flag_names if name not in repo_flags_by_name
154+
]
155+
if missing_flag_names:
156+
log.warning(
157+
"Repository flag not found for flag(s). Created repository flag(s).",
158+
extra={"repoid": repository_id, "flag_names": missing_flag_names},
159+
)
160+
for flag_name in missing_flag_names:
161+
new_repo_flag = RepositoryFlag(
154162
repository_id=repository_id,
155163
flag_name=flag_name,
156164
)
157-
db_session.add(repositoryflag)
158-
db_session.flush()
159-
160-
flag_comparison_entry = (
161-
db_session.query(CompareFlag)
162-
.filter_by(
163-
commit_comparison_id=comparison.id,
164-
repositoryflag_id=repositoryflag.id,
165-
)
166-
.first()
165+
db_session.add(new_repo_flag)
166+
repo_flags_by_name[flag_name] = new_repo_flag
167+
db_session.flush()
168+
169+
# Batch-fetch all existing CompareFlag records for this comparison
170+
repositoryflag_ids = [rf.id for rf in repo_flags_by_name.values()]
171+
existing_flag_comparisons = (
172+
db_session.query(CompareFlag)
173+
.filter(
174+
CompareFlag.commit_comparison_id == comparison.id,
175+
CompareFlag.repositoryflag_id.in_(repositoryflag_ids),
176+
)
177+
.all()
178+
)
179+
flag_comparisons_by_repositoryflag_id = {
180+
fc.repositoryflag_id: fc for fc in existing_flag_comparisons
181+
}
182+
183+
# Now iterate using the pre-fetched data — no per-flag DB queries
184+
for flag_name in flag_names:
185+
totals = self.get_flag_comparison_totals(flag_name, comparison_proxy)
186+
repositoryflag = repo_flags_by_name[flag_name]
187+
flag_comparison_entry = flag_comparisons_by_repositoryflag_id.get(
188+
repositoryflag.id
167189
)
168190

169191
if not flag_comparison_entry:

0 commit comments

Comments
 (0)