fix(perf): Add indices to hot paths for repository querying (#526)

This commit is contained in:
Brendan Kellam 2025-09-19 15:42:48 -07:00 committed by GitHub
parent 5dcc538878
commit 5bc8fc323a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 106 additions and 0 deletions

View file

@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Changed
- Improved repository query performance by adding db indices. [#526](https://github.com/sourcebot-dev/sourcebot/pull/526)
## [4.7.1] - 2025-09-19 ## [4.7.1] - 2025-09-19
### Fixed ### Fixed

View file

@ -0,0 +1,5 @@
-- CreateIndex
CREATE INDEX "Repo_orgId_idx" ON "Repo"("orgId");
-- CreateIndex
CREATE INDEX "RepoToConnection_repoId_connectionId_idx" ON "RepoToConnection"("repoId", "connectionId");

View file

@ -71,6 +71,7 @@ model Repo {
searchContexts SearchContext[] searchContexts SearchContext[]
@@unique([external_id, external_codeHostUrl, orgId]) @@unique([external_id, external_codeHostUrl, orgId])
@@index([orgId])
} }
model SearchContext { model SearchContext {
@ -119,6 +120,7 @@ model RepoToConnection {
repoId Int repoId Int
@@id([connectionId, repoId]) @@id([connectionId, repoId])
@@index([repoId, connectionId])
} }
model Invite { model Invite {

View file

@ -4,6 +4,8 @@ import { migrateDuplicateConnections } from "./scripts/migrate-duplicate-connect
import { injectAuditData } from "./scripts/inject-audit-data"; import { injectAuditData } from "./scripts/inject-audit-data";
import { confirmAction } from "./utils"; import { confirmAction } from "./utils";
import { createLogger } from "@sourcebot/logger"; import { createLogger } from "@sourcebot/logger";
import { injectRepoData } from "./scripts/inject-repo-data";
import { testRepoQueryPerf } from "./scripts/test-repo-query-perf";
export interface Script { export interface Script {
run: (prisma: PrismaClient) => Promise<void>; run: (prisma: PrismaClient) => Promise<void>;
@ -12,6 +14,8 @@ export interface Script {
export const scripts: Record<string, Script> = { export const scripts: Record<string, Script> = {
"migrate-duplicate-connections": migrateDuplicateConnections, "migrate-duplicate-connections": migrateDuplicateConnections,
"inject-audit-data": injectAuditData, "inject-audit-data": injectAuditData,
"inject-repo-data": injectRepoData,
"test-repo-query-perf": testRepoQueryPerf,
} }
const parser = new ArgumentParser(); const parser = new ArgumentParser();

View file

@ -0,0 +1,64 @@
import { Script } from "../scriptRunner";
import { PrismaClient } from "../../dist";
import { createLogger } from "@sourcebot/logger";
const logger = createLogger('inject-repo-data');
const NUM_REPOS = 100000;
export const injectRepoData: Script = {
run: async (prisma: PrismaClient) => {
const orgId = 1;
// Check if org exists
const org = await prisma.org.findUnique({
where: { id: orgId }
});
if (!org) {
await prisma.org.create({
data: {
id: orgId,
name: 'Test Org',
domain: 'test-org.com'
}
});
}
const connection = await prisma.connection.create({
data: {
orgId,
name: 'test-connection',
connectionType: 'github',
config: {}
}
});
logger.info(`Creating ${NUM_REPOS} repos...`);
for (let i = 0; i < NUM_REPOS; i++) {
await prisma.repo.create({
data: {
name: `test-repo-${i}`,
isFork: false,
isArchived: false,
metadata: {},
cloneUrl: `https://github.com/test-org/test-repo-${i}`,
webUrl: `https://github.com/test-org/test-repo-${i}`,
orgId,
external_id: `test-repo-${i}`,
external_codeHostType: 'github',
external_codeHostUrl: 'https://github.com',
connections: {
create: {
connectionId: connection.id,
}
}
}
});
}
logger.info(`Created ${NUM_REPOS} repos.`);
}
};

View file

@ -0,0 +1,28 @@
import { Script } from "../scriptRunner";
import { PrismaClient } from "../../dist";
import { createLogger } from "@sourcebot/logger";
const logger = createLogger('test-repo-query-perf');
export const testRepoQueryPerf: Script = {
run: async (prisma: PrismaClient) => {
const start = Date.now();
const allRepos = await prisma.repo.findMany({
where: {
orgId: 1,
},
include: {
connections: {
include: {
connection: true,
}
}
}
});
const durationMs = Date.now() - start;
logger.info(`Found ${allRepos.length} repos in ${durationMs}ms`);
}
};