perf: fix database query performance bottlenecks (#1982)
* perf: fix database query performance bottlenecks - Add composite index on workspace_repos(workspace_id, repo_id) to optimize lookup queries that were taking up to 5 seconds - Add composite index on merges(merge_type, pr_status) to optimize status filtering queries that were taking 2+ seconds - Fix N+1 query pattern in workspace_repos.create_many by wrapping inserts in a transaction - Fix N+1 query pattern in get_task_attempt_branch_status by batch fetching all merges upfront instead of querying per repo These changes address significant performance bottlenecks identified in production logs where simple lookup queries were experiencing multi-second latencies. * cargo fmt * run sqlx prepare --------- Co-authored-by: Solomon <abcpro11051@disroot.org>
This commit is contained in:
@@ -728,6 +728,20 @@ pub async fn get_task_attempt_branch_status(
|
||||
.await?;
|
||||
let workspace_dir = PathBuf::from(&container_ref);
|
||||
|
||||
// Batch fetch all merges for the workspace to avoid N+1 queries
|
||||
let all_merges = Merge::find_by_workspace_id(pool, workspace.id).await?;
|
||||
let merges_by_repo: HashMap<Uuid, Vec<Merge>> =
|
||||
all_merges
|
||||
.into_iter()
|
||||
.fold(HashMap::new(), |mut acc, merge| {
|
||||
let repo_id = match &merge {
|
||||
Merge::Direct(dm) => dm.repo_id,
|
||||
Merge::Pr(pm) => pm.repo_id,
|
||||
};
|
||||
acc.entry(repo_id).or_insert_with(Vec::new).push(merge);
|
||||
acc
|
||||
});
|
||||
|
||||
let mut results = Vec::with_capacity(repositories.len());
|
||||
|
||||
for repo in repositories {
|
||||
@@ -735,7 +749,7 @@ pub async fn get_task_attempt_branch_status(
|
||||
continue;
|
||||
};
|
||||
|
||||
let repo_merges = Merge::find_by_workspace_and_repo_id(pool, workspace.id, repo.id).await?;
|
||||
let repo_merges = merges_by_repo.get(&repo.id).cloned().unwrap_or_default();
|
||||
|
||||
let worktree_path = workspace_dir.join(&repo.name);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user